From bf1f142a72e439e3a1cdc6d67b4c4659dd944262 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 20 Nov 2021 18:40:38 +0100 Subject: [PATCH 01/20] Fix warnings --- test/unit/Common/utMesh.cpp | 11 ++++++----- test/unit/utColladaExport.cpp | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/test/unit/Common/utMesh.cpp b/test/unit/Common/utMesh.cpp index da0c1084d..c1a532407 100644 --- a/test/unit/Common/utMesh.cpp +++ b/test/unit/Common/utMesh.cpp @@ -60,7 +60,7 @@ protected: }; TEST_F(utMesh, emptyMeshHasNoContentTest) { - EXPECT_EQ(0, mesh->mName.length); + EXPECT_EQ(0u, mesh->mName.length); EXPECT_FALSE(mesh->HasPositions()); EXPECT_FALSE(mesh->HasFaces()); EXPECT_FALSE(mesh->HasNormals()); @@ -69,8 +69,8 @@ TEST_F(utMesh, emptyMeshHasNoContentTest) { EXPECT_FALSE(mesh->HasVertexColors(AI_MAX_NUMBER_OF_COLOR_SETS)); EXPECT_FALSE(mesh->HasTextureCoords(0)); EXPECT_FALSE(mesh->HasTextureCoords(AI_MAX_NUMBER_OF_TEXTURECOORDS)); - EXPECT_EQ(0, mesh->GetNumUVChannels()); - EXPECT_EQ(0, mesh->GetNumColorChannels()); + EXPECT_EQ(0u, mesh->GetNumUVChannels()); + EXPECT_EQ(0u, mesh->GetNumColorChannels()); EXPECT_FALSE(mesh->HasBones()); EXPECT_FALSE(mesh->HasTextureCoordsName(0)); EXPECT_FALSE(mesh->HasTextureCoordsName(AI_MAX_NUMBER_OF_TEXTURECOORDS)); @@ -80,8 +80,8 @@ TEST_F(utMesh, setTextureCoordsName) { EXPECT_FALSE(mesh->HasTextureCoordsName(0)); const aiString texcoords_name("texcoord_name"); mesh->SetTextureCoordsName(0, texcoords_name); - EXPECT_TRUE(mesh->HasTextureCoordsName(0)); - EXPECT_FALSE(mesh->HasTextureCoordsName(1)); + EXPECT_TRUE(mesh->HasTextureCoordsName(0u)); + EXPECT_FALSE(mesh->HasTextureCoordsName(1u)); ASSERT_NE(nullptr, mesh->mTextureCoordsNames); ASSERT_NE(nullptr, mesh->mTextureCoordsNames[0]); EXPECT_STREQ(texcoords_name.C_Str(), mesh->mTextureCoordsNames[0]->C_Str()); @@ -94,3 +94,4 @@ TEST_F(utMesh, setTextureCoordsName) { EXPECT_EQ(nullptr, mesh->mTextureCoordsNames[0]); EXPECT_EQ(nullptr, mesh->GetTextureCoordsName(0)); } + diff --git a/test/unit/utColladaExport.cpp b/test/unit/utColladaExport.cpp index d0c22ffb8..e588872f0 100644 --- a/test/unit/utColladaExport.cpp +++ b/test/unit/utColladaExport.cpp @@ -124,9 +124,9 @@ TEST_F(utColladaExport, testExportLight) { ASSERT_NE(pTest, nullptr); ASSERT_TRUE(pTest->HasLights()); - const unsigned int origNumLights(pTest->mNumLights); + const unsigned int origNumLights = pTest->mNumLights; // There are FIVE!!! LIGHTS!!! - EXPECT_EQ(5, origNumLights) << "lights.dae should contain five lights"; + EXPECT_EQ(5u, origNumLights) << "lights.dae should contain five lights"; std::vector origLights(5); for (size_t i = 0; i < origNumLights; i++) { From 067c5d9ec4fff4b7779bf54bfa9dc44efd9cc64a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 16 Feb 2022 00:17:26 +0100 Subject: [PATCH 02/20] Refactoring: add usage of ai_epsilon to fbx. --- code/AssetLib/FBX/FBXCommon.h | 2 ++ code/AssetLib/FBX/FBXConverter.cpp | 3 ++- include/assimp/defs.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/FBX/FBXCommon.h b/code/AssetLib/FBX/FBXCommon.h index 54e2e9e50..ec7459c9e 100644 --- a/code/AssetLib/FBX/FBXCommon.h +++ b/code/AssetLib/FBX/FBXCommon.h @@ -80,8 +80,10 @@ enum TransformInheritance { TransformInheritance_MAX // end-of-enum sentinel }; + } // namespace FBX } // namespace Assimp + #endif // ASSIMP_BUILD_NO_FBX_EXPORTER #endif // AI_FBXCOMMON_H_INC diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index 3cefed023..d7b7e0ef3 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -3187,7 +3187,8 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name, } bool ok = false; - const float zero_epsilon = 1e-6f; + + const float zero_epsilon = ai_epsilon; const aiVector3D& preRotation = PropertyGet(props, "PreRotation", ok); if (ok && preRotation.SquareLength() > zero_epsilon) { diff --git a/include/assimp/defs.h b/include/assimp/defs.h index 9c4422584..b85f14b7e 100644 --- a/include/assimp/defs.h +++ b/include/assimp/defs.h @@ -283,7 +283,7 @@ typedef unsigned int ai_uint; #define AI_RAD_TO_DEG(x) ((x) * (ai_real)57.2957795) /* Numerical limits */ -static const ai_real ai_epsilon = (ai_real)0.00001; +static const ai_real ai_epsilon = (ai_real) 1e-6; /* Support for big-endian builds */ #if defined(__BYTE_ORDER__) From 76a7614c4b7c76922a8449fda9b3982adcb5268f Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 16 Feb 2022 20:07:27 +0100 Subject: [PATCH 03/20] Adapt ai_epsilon to code --- code/AssetLib/Collada/ColladaLoader.cpp | 6 +++--- code/AssetLib/FBX/FBXConverter.cpp | 2 +- code/AssetLib/IFC/IFCBoolean.cpp | 18 +++++++++--------- code/AssetLib/IFC/IFCGeometry.cpp | 12 +++++------- code/AssetLib/IFC/IFCOpenings.cpp | 6 +++--- code/AssetLib/IFC/IFCUtil.cpp | 24 +++++++++++------------- code/PostProcessing/FindDegenerates.cpp | 2 +- include/assimp/matrix3x3.h | 2 +- include/assimp/matrix4x4.h | 2 +- include/assimp/quaternion.h | 2 +- include/assimp/vector2.h | 2 +- include/assimp/vector3.h | 2 +- test/unit/utglTF2ImportExport.cpp | 2 +- 13 files changed, 39 insertions(+), 43 deletions(-) diff --git a/code/AssetLib/Collada/ColladaLoader.cpp b/code/AssetLib/Collada/ColladaLoader.cpp index 447055082..775ba44d2 100644 --- a/code/AssetLib/Collada/ColladaLoader.cpp +++ b/code/AssetLib/Collada/ColladaLoader.cpp @@ -357,9 +357,9 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node out->mAngleInnerCone = AI_DEG_TO_RAD(srcLight->mFalloffAngle); // ... some extension magic. - if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - 1e-6f)) { + if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - ai_epsilon)) { // ... some deprecation magic. - if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - 1e-6f)) { + if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - ai_epsilon)) { // Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess .... // epsilon chosen to be 0.1 float f = 1.0f; @@ -1065,7 +1065,7 @@ void insertMorphTimeValue(std::vector &values, float time, floa return; } for (unsigned int i = 0; i < values.size(); i++) { - if (std::abs(time - values[i].mTime) < 1e-6f) { + if (std::abs(time - values[i].mTime) < ai_epsilon) { values[i].mKeys.push_back(k); return; } else if (time > values[i].mTime && time < values[i + 1].mTime) { diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index d7b7e0ef3..39db79a3e 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -653,7 +653,7 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) { const PropertyTable &props = model.Props(); bool ok; - const float zero_epsilon = 1e-6f; + const float zero_epsilon = ai_epsilon; 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); diff --git a/code/AssetLib/IFC/IFCBoolean.cpp b/code/AssetLib/IFC/IFCBoolean.cpp index ee255e612..36912a7d8 100644 --- a/code/AssetLib/IFC/IFCBoolean.cpp +++ b/code/AssetLib/IFC/IFCBoolean.cpp @@ -66,12 +66,12 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe // if segment ends on plane, do not report a hit. We stay on that side until a following segment starting at this // point leaves the plane through the other side - if (std::abs(dotOne + dotTwo) < 1e-6) + if (std::abs(dotOne + dotTwo) < ai_epsilon) return false; // if segment starts on the plane, report a hit only if the end lies on the *other* side - if (std::abs(dotTwo) < 1e-6) { - if ((assumeStartOnWhiteSide && dotOne + dotTwo < 1e-6) || (!assumeStartOnWhiteSide && dotOne + dotTwo > -1e-6)) { + if (std::abs(dotTwo) < ai_epsilon) { + if ((assumeStartOnWhiteSide && dotOne + dotTwo < ai_epsilon) || (!assumeStartOnWhiteSide && dotOne + dotTwo > -ai_epsilon)) { out = e0; return true; } else { @@ -81,7 +81,7 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe // ignore if segment is parallel to plane and far away from it on either side // Warning: if there's a few thousand of such segments which slowly accumulate beyond the epsilon, no hit would be registered - if (std::abs(dotOne) < 1e-6) + if (std::abs(dotOne) < ai_epsilon) return false; // t must be in [0..1] if the intersection point is within the given segment @@ -163,7 +163,7 @@ void ProcessBooleanHalfSpaceDifference(const Schema_2x3::IfcHalfSpaceSolid *hs, for (iit = begin; iit != end; vidx += *iit++) { unsigned int newcount = 0; - bool isAtWhiteSide = (in[vidx] - p) * n > -1e-6; + bool isAtWhiteSide = (in[vidx] - p) * n > -ai_epsilon; for (unsigned int i = 0; i < *iit; ++i) { const IfcVector3 &e0 = in[vidx + i], e1 = in[vidx + (i + 1) % *iit]; @@ -259,7 +259,7 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const // segment-segment intersection // solve b0 + b*s = e0 + e*t for (s,t) const IfcFloat det = (-b.x * e.y + e.x * b.y); - if (std::abs(det) < 1e-6) { + if (std::abs(det) < ai_epsilon) { // no solutions (parallel lines) continue; } @@ -316,7 +316,7 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const // for a valid intersection, s and t should be in range [0,1]. Including a bit of epsilon on s, potential double // hits on two consecutive boundary segments are filtered - if (s >= -1e-6 * b_sqlen_inv && s <= 1.0 + 1e-6 * b_sqlen_inv && t >= 0.0 && (t <= 1.0 || halfOpen)) { + if (s >= -ai_epsilon * b_sqlen_inv && s <= 1.0 + ai_epsilon * b_sqlen_inv && t >= 0.0 && (t <= 1.0 || halfOpen)) { // only insert the point into the list if it is sufficiently far away from the previous intersection point. // This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments. if (!intersect_results.empty() && intersect_results.back().first == i - 1) { @@ -431,14 +431,14 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly // if the poly is parallel to the plane, put it completely on the black or white side if (std::abs(polyNormal * n) > 0.9999) { - bool isOnWhiteSide = (srcVertices[0] - p) * n > -1e-6; + bool isOnWhiteSide = (srcVertices[0] - p) * n > -ai_epsilon; std::vector &targetSide = isOnWhiteSide ? whiteside : blackside; targetSide.insert(targetSide.end(), srcVertices, srcVertices + srcVtxCount); } else { // otherwise start building one polygon for each side. Whenever the current line segment intersects the plane // we put a point there as an end of the current segment. Then we switch to the other side, put a point there, too, // as a beginning of the current segment, and simply continue accumulating vertices. - bool isCurrentlyOnWhiteSide = ((srcVertices[0]) - p) * n > -1e-6; + bool isCurrentlyOnWhiteSide = ((srcVertices[0]) - p) * n > -ai_epsilon; for (size_t a = 0; a < srcVtxCount; ++a) { IfcVector3 e0 = srcVertices[a]; IfcVector3 e1 = srcVertices[(a + 1) % srcVtxCount]; diff --git a/code/AssetLib/IFC/IFCGeometry.cpp b/code/AssetLib/IFC/IFCGeometry.cpp index 4c088955f..401ff9de6 100644 --- a/code/AssetLib/IFC/IFCGeometry.cpp +++ b/code/AssetLib/IFC/IFCGeometry.cpp @@ -380,21 +380,19 @@ void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh& bool take_any = false; for (unsigned int j = 0; j < 2; ++j, take_any = true) { - if ((last_dir == 0 || take_any) && std::abs(d.x) > 1e-6) { + if ((last_dir == 0 || take_any) && std::abs(d.x) > ai_epsilon) { q.y = startvec.y; q.z = startvec.z; q.x = -(d.y * q.y + d.z * q.z) / d.x; last_dir = 0; break; - } - else if ((last_dir == 1 || take_any) && std::abs(d.y) > 1e-6) { + } else if ((last_dir == 1 || take_any) && std::abs(d.y) > ai_epsilon) { q.x = startvec.x; q.z = startvec.z; q.y = -(d.x * q.x + d.z * q.z) / d.y; last_dir = 1; break; - } - else if ((last_dir == 2 && std::abs(d.z) > 1e-6) || take_any) { + } else if ((last_dir == 2 && std::abs(d.z) > ai_epsilon) || take_any) { q.y = startvec.y; q.x = startvec.x; q.z = -(d.y * q.y + d.x * q.x) / d.z; @@ -529,7 +527,7 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect return m; } -const auto closeDistance = 1e-6; +constexpr auto closeDistance = ai_epsilon; bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt2) { if(pt1.Coordinates.size() != pt2.Coordinates.size()) @@ -561,7 +559,7 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te // Outline: 'curve' is now a list of vertex points forming the underlying profile, extrude along the given axis, // forming new triangles. const bool has_area = solid.SweptArea->ProfileType == "AREA" && curve.mVerts.size() > 2; - if( solid.Depth < 1e-6 ) { + if (solid.Depth < ai_epsilon) { if( has_area ) { result.Append(curve); } diff --git a/code/AssetLib/IFC/IFCOpenings.cpp b/code/AssetLib/IFC/IFCOpenings.cpp index c261a24b0..46cccd02c 100644 --- a/code/AssetLib/IFC/IFCOpenings.cpp +++ b/code/AssetLib/IFC/IFCOpenings.cpp @@ -1133,7 +1133,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector& out_contour, const TempMesh } for(size_t i = 0; i < out_contour.size(); ++i) { - ai_assert((out_contour[i]-out_contour2[i]).SquareLength() < 1e-6); + ai_assert((out_contour[i] - out_contour2[i]).SquareLength() < ai_epsilon); } #endif @@ -1435,7 +1435,7 @@ std::vector GetContourInPlane2D(std::shared_ptr mesh,IfcMa const auto outernor = ((mesh->mVerts[2] - mesh->mVerts[0]) ^ (mesh->mVerts[1] - mesh->mVerts[0])).Normalize(); const IfcFloat dot = planeNor * outernor; - if(std::fabs(dot) < 1.f - 1e-6f) { + if (std::fabs(dot) < 1.f - ai_epsilon) { std::stringstream msg; msg << "Skipping: Unaligned opening (" << planeNor.x << ", " << planeNor.y << ", " << planeNor.z << ")"; msg << " . ( " << outernor.x << ", " << outernor.y << ", " << outernor.z << ") = " << dot; @@ -1476,7 +1476,7 @@ std::vector GetContourInPlane2D(std::shared_ptr mesh,IfcMa return contour; } -const float close { 1e-6f }; +constexpr float close{ ai_epsilon }; static bool isClose(IfcVector2 first,IfcVector2 second) { auto diff = (second - first); diff --git a/code/AssetLib/IFC/IFCUtil.cpp b/code/AssetLib/IFC/IFCUtil.cpp index 2ff0d6a58..6b378c1da 100644 --- a/code/AssetLib/IFC/IFCUtil.cpp +++ b/code/AssetLib/IFC/IFCUtil.cpp @@ -228,25 +228,24 @@ void TempMesh::ComputePolygonNormals(std::vector& normals, // ------------------------------------------------------------------------------------------------ // Compute the normal of the last polygon in the given mesh -IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const -{ +IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const { return ComputePolygonNormal(&mVerts[mVerts.size() - mVertcnt.back()], mVertcnt.back(), normalize); } -struct CompareVector -{ - bool operator () (const IfcVector3& a, const IfcVector3& b) const - { +struct CompareVector { + bool operator () (const IfcVector3& a, const IfcVector3& b) const { IfcVector3 d = a - b; - IfcFloat eps = 1e-6; + IfcFloat eps = ai_epsilon; return d.x < -eps || (std::abs(d.x) < eps && d.y < -eps) || (std::abs(d.x) < eps && std::abs(d.y) < eps && d.z < -eps); } }; -struct FindVector -{ + +struct FindVector { IfcVector3 v; FindVector(const IfcVector3& p) : v(p) { } - bool operator () (const IfcVector3& p) { return FuzzyVectorCompare(1e-6)(p, v); } + bool operator()(const IfcVector3 &p) { + return FuzzyVectorCompare(ai_epsilon)(p, v); + } }; // ------------------------------------------------------------------------------------------------ @@ -357,8 +356,7 @@ void TempMesh::FixupFaceOrientation() // to reverse the neighbour nb_vidx = (nb_vidx + 1) % nbvc; size_t oursideidx = (a + 1) % vc; - if( FuzzyVectorCompare(1e-6)(mVerts[vsi + oursideidx], mVerts[nbvsi + nb_vidx]) ) - { + if (FuzzyVectorCompare(ai_epsilon)(mVerts[vsi + oursideidx], mVerts[nbvsi + nb_vidx])) { std::reverse(mVerts.begin() + nbvsi, mVerts.begin() + nbvsi + nbvc); std::reverse(neighbour.begin() + nbvsi, neighbour.begin() + nbvsi + nbvc); for (size_t aa = 0; aa < nbvc - 1; ++aa) { @@ -564,7 +562,7 @@ void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in) out[static_cast(i)] = in.DirectionRatios[i]; } const IfcFloat len = out.Length(); - if (len<1e-6) { + if (len < ai_epsilon) { IFCImporter::LogWarn("direction vector magnitude too small, normalization would result in a division by zero"); return; } diff --git a/code/PostProcessing/FindDegenerates.cpp b/code/PostProcessing/FindDegenerates.cpp index de46d5630..0bbf421d2 100644 --- a/code/PostProcessing/FindDegenerates.cpp +++ b/code/PostProcessing/FindDegenerates.cpp @@ -221,7 +221,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) { if ( mConfigCheckAreaOfTriangle ) { if ( face.mNumIndices == 3 ) { ai_real area = calculateAreaOfTriangle( face, mesh ); - if ( area < 1e-6 ) { + if (area < ai_epsilon) { if ( mConfigRemoveDegenerates ) { remove_me[ a ] = true; ++deg; diff --git a/include/assimp/matrix3x3.h b/include/assimp/matrix3x3.h index 5ae31bbeb..74382e263 100644 --- a/include/assimp/matrix3x3.h +++ b/include/assimp/matrix3x3.h @@ -95,7 +95,7 @@ public: bool operator== (const aiMatrix3x3t& m) const; bool operator!= (const aiMatrix3x3t& m) const; - bool Equal(const aiMatrix3x3t& m, TReal epsilon = 1e-6) const; + bool Equal(const aiMatrix3x3t &m, TReal epsilon = ai_epsilon) const; template operator aiMatrix3x3t () const; diff --git a/include/assimp/matrix4x4.h b/include/assimp/matrix4x4.h index 07abf4711..67e0e356e 100644 --- a/include/assimp/matrix4x4.h +++ b/include/assimp/matrix4x4.h @@ -110,7 +110,7 @@ public: bool operator== (const aiMatrix4x4t& m) const; bool operator!= (const aiMatrix4x4t& m) const; - bool Equal(const aiMatrix4x4t& m, TReal epsilon = 1e-6) const; + bool Equal(const aiMatrix4x4t &m, TReal epsilon = ai_epsilon) const; // matrix multiplication. aiMatrix4x4t& operator *= (const aiMatrix4x4t& m); diff --git a/include/assimp/quaternion.h b/include/assimp/quaternion.h index aa92ea577..b6d0a5681 100644 --- a/include/assimp/quaternion.h +++ b/include/assimp/quaternion.h @@ -92,7 +92,7 @@ public: // transform vector by matrix aiQuaterniont& operator *= (const aiMatrix4x4t& mat); - bool Equal(const aiQuaterniont& o, TReal epsilon = 1e-6) const; + bool Equal(const aiQuaterniont &o, TReal epsilon = ai_epsilon) const; public: diff --git a/include/assimp/vector2.h b/include/assimp/vector2.h index 333c094d4..f06e9441d 100644 --- a/include/assimp/vector2.h +++ b/include/assimp/vector2.h @@ -85,7 +85,7 @@ public: bool operator== (const aiVector2t& other) const; bool operator!= (const aiVector2t& other) const; - bool Equal(const aiVector2t& other, TReal epsilon = 1e-6) const; + bool Equal(const aiVector2t &other, TReal epsilon = ai_epsilon) const; aiVector2t& operator= (TReal f); const aiVector2t SymMul(const aiVector2t& o); diff --git a/include/assimp/vector3.h b/include/assimp/vector3.h index c191e1ee7..a886def1d 100644 --- a/include/assimp/vector3.h +++ b/include/assimp/vector3.h @@ -114,7 +114,7 @@ public: bool operator < (const aiVector3t& other) const; /// @brief - bool Equal(const aiVector3t& other, TReal epsilon = 1e-6) const; + bool Equal(const aiVector3t &other, TReal epsilon = ai_epsilon) const; template operator aiVector3t () const; diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index 84f940c66..00f76aa47 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -573,7 +573,7 @@ TEST_F(utglTF2ImportExport, export_normalized_normals) { scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxBadNormals-glTF-Binary/BoxBadNormals_out.glb", aiProcess_ValidateDataStructure); for ( auto i = 0u; i < scene->mMeshes[0]->mNumVertices; ++i ) { const auto length = scene->mMeshes[0]->mNormals[i].Length(); - EXPECT_TRUE(abs(length) < 1e-6 || abs(length - 1) < 1e-6); + EXPECT_TRUE(abs(length) < 1e-6 || abs(length - 1) < ai_epsilon); } } From 9e23d771bc66db6a75a3342ae586389989109f46 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 16 Feb 2022 21:19:17 +0100 Subject: [PATCH 04/20] Fix invalid initialization of constexpr. --- code/AssetLib/IFC/IFCGeometry.cpp | 2 +- include/assimp/defs.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/AssetLib/IFC/IFCGeometry.cpp b/code/AssetLib/IFC/IFCGeometry.cpp index 401ff9de6..ef5954251 100644 --- a/code/AssetLib/IFC/IFCGeometry.cpp +++ b/code/AssetLib/IFC/IFCGeometry.cpp @@ -527,7 +527,7 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect return m; } -constexpr auto closeDistance = ai_epsilon; +const auto closeDistance = ai_epsilon; bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt2) { if(pt1.Coordinates.size() != pt2.Coordinates.size()) diff --git a/include/assimp/defs.h b/include/assimp/defs.h index b85f14b7e..0626a8d8a 100644 --- a/include/assimp/defs.h +++ b/include/assimp/defs.h @@ -279,8 +279,8 @@ typedef unsigned int ai_uint; #define AI_MATH_HALF_PI_F (AI_MATH_PI_F * 0.5f) /* Tiny macro to convert from radians to degrees and back */ -#define AI_DEG_TO_RAD(x) ((x) * (ai_real)0.0174532925) -#define AI_RAD_TO_DEG(x) ((x) * (ai_real)57.2957795) +#define AI_DEG_TO_RAD(x) ((x) * (ai_real) 0.0174532925) +#define AI_RAD_TO_DEG(x) ((x) * (ai_real) 57.2957795) /* Numerical limits */ static const ai_real ai_epsilon = (ai_real) 1e-6; From 9bf5d01469a4afd0804c641529c71f8aceb63e72 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 16 Feb 2022 21:22:35 +0100 Subject: [PATCH 05/20] Fix invalid initialization of constexpr. --- code/AssetLib/IFC/IFCOpenings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/IFC/IFCOpenings.cpp b/code/AssetLib/IFC/IFCOpenings.cpp index 46cccd02c..74200195b 100644 --- a/code/AssetLib/IFC/IFCOpenings.cpp +++ b/code/AssetLib/IFC/IFCOpenings.cpp @@ -1476,7 +1476,7 @@ std::vector GetContourInPlane2D(std::shared_ptr mesh,IfcMa return contour; } -constexpr float close{ ai_epsilon }; +const float close{ ai_epsilon }; static bool isClose(IfcVector2 first,IfcVector2 second) { auto diff = (second - first); From 33a48c6ca606706f97f83954c22651455c388903 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 17 Feb 2022 05:47:34 -0500 Subject: [PATCH 06/20] cmake: Fix assimp target install rule fully specifying component This commit ensures generated install rules for the assimp target are all consistently associated with components named after LIBASSIMP_COMPONENT or LIBASSIMP-DEV_COMPONENT CMake variables. It streamlines the packaging of specific components of assimp in client projects leveraging the CPACK_INSTALL_CMAKE_PROJECTS variable. Failing to do so leads to "/path/to/assimp-build/code/cmake_install.cmake" file having install rules associated with a component called "Unspecified". See https://cmake.org/cmake/help/v3.10/command/install.html#installing-targets and https://cmake.org/cmake/help/v3.22/module/CPack.html#variable:CPACK_INSTALL_CMAKE_PROJECTS --- code/CMakeLists.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 5936d6d06..7a2f8a109 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1317,11 +1317,10 @@ ENDIF () INSTALL( TARGETS assimp EXPORT "${TARGETS_EXPORT_NAME}" - LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR} - ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR} - RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR} - FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR} - COMPONENT ${LIBASSIMP_COMPONENT} + LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT} + ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP-DEV_COMPONENT} + RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT} + FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT} INCLUDES DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR} ) INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp COMPONENT assimp-dev) From 17123ed4a156db742d7772c911efe24ed924fd0f Mon Sep 17 00:00:00 2001 From: Terence Russell Date: Thu, 17 Feb 2022 22:10:46 -0700 Subject: [PATCH 07/20] Add support for bump -bm (bump/normal multiplier) --- code/AssetLib/Obj/ObjFileData.h | 6 +- code/AssetLib/Obj/ObjFileImporter.cpp | 7 +++ code/AssetLib/Obj/ObjFileMtlImporter.cpp | 6 +- include/assimp/ObjMaterial.h | 77 ++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 include/assimp/ObjMaterial.h diff --git a/code/AssetLib/Obj/ObjFileData.h b/code/AssetLib/Obj/ObjFileData.h index bc65058ac..3d504d0bb 100644 --- a/code/AssetLib/Obj/ObjFileData.h +++ b/code/AssetLib/Obj/ObjFileData.h @@ -195,6 +195,9 @@ struct Material { //! PBR Anisotropy ai_real anisotropy; + //! bump map multipler (normal map scalar)(-bm) + ai_real bump_multiplier; + //! Constructor Material() : diffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)), @@ -208,7 +211,8 @@ struct Material { sheen(ai_real(1.0), ai_real(1.0), ai_real(1.0)), clearcoat_thickness(ai_real(0.0)), clearcoat_roughness(ai_real(0.0)), - anisotropy(ai_real(0.0)) { + anisotropy(ai_real(0.0)), + bump_multiplier(ai_real(1.0)) { std::fill_n(clamp, static_cast(TextureTypeCount), false); } diff --git a/code/AssetLib/Obj/ObjFileImporter.cpp b/code/AssetLib/Obj/ObjFileImporter.cpp index fd062552f..6dd26956e 100644 --- a/code/AssetLib/Obj/ObjFileImporter.cpp +++ b/code/AssetLib/Obj/ObjFileImporter.cpp @@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include static const aiImporterDesc desc = { @@ -657,6 +658,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc if (0 != pCurrentMaterial->textureBump.length) { mat->AddProperty(&pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_HEIGHT(0)); + if (pCurrentMaterial->bump_multiplier != 1.0) { + mat->AddProperty(&pCurrentMaterial->bump_multiplier, 1, AI_MATKEY_OBJ_BUMPMULT_HEIGHT(0)); + } if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType]) { addTextureMappingModeProperty(mat, aiTextureType_HEIGHT); } @@ -665,6 +669,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc if (0 != pCurrentMaterial->textureNormal.length) { mat->AddProperty(&pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_NORMALS(0)); + if (pCurrentMaterial->bump_multiplier != 1.0) { + mat->AddProperty(&pCurrentMaterial->bump_multiplier, 1, AI_MATKEY_OBJ_BUMPMULT_NORMALS(0)); + } if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType]) { addTextureMappingModeProperty(mat, aiTextureType_NORMALS); } diff --git a/code/AssetLib/Obj/ObjFileMtlImporter.cpp b/code/AssetLib/Obj/ObjFileMtlImporter.cpp index 7d5930594..2441c17f2 100644 --- a/code/AssetLib/Obj/ObjFileMtlImporter.cpp +++ b/code/AssetLib/Obj/ObjFileMtlImporter.cpp @@ -472,7 +472,11 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString } skipToken = 2; - } else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast(BumpOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast(ChannelOption.size()))) { + } else if (!ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast(BumpOption.size()))) { + DataArrayIt it = getNextToken(m_DataIt, m_DataItEnd); + getFloat(it, m_DataItEnd, m_pModel->m_pCurrentMaterial->bump_multiplier); + skipToken = 2; + } else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast(ChannelOption.size()))) { skipToken = 2; } else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast(ModifyMapOption.size()))) { skipToken = 3; diff --git a/include/assimp/ObjMaterial.h b/include/assimp/ObjMaterial.h new file mode 100644 index 000000000..39894a696 --- /dev/null +++ b/include/assimp/ObjMaterial.h @@ -0,0 +1,77 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file OBJMATERIAL.h + * @brief Obj-specific material macros + * + */ + +#ifndef AI_OBJMATERIAL_H_INC +#define AI_OBJMATERIAL_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +// --------------------------------------------------------------------------- +// Pure key names for all obj texture-related properties +//! @cond MATS_DOC_FULL + +// support for bump -bm +#define _AI_MATKEY_OBJ_BUMPMULT_BASE "$tex.bumpmult" +//! @endcond + +// --------------------------------------------------------------------------- +#define AI_MATKEY_OBJ_BUMPMULT(type, N) _AI_MATKEY_OBJ_BUMPMULT_BASE, type, N + +//! @cond MATS_DOC_FULL +#define AI_MATKEY_OBJ_BUMPMULT_NORMALS(N) \ + AI_MATKEY_OBJ_BUMPMULT(aiTextureType_NORMALS, N) + +#define AI_MATKEY_OBJ_BUMPMULT_HEIGHT(N) \ + AI_MATKEY_OBJ_BUMPMULT(aiTextureType_HEIGHT, N) + +//! @endcond + + +#endif From efc60076dc951b0b0cfd9612fd8b5382a9e1e7e4 Mon Sep 17 00:00:00 2001 From: ChenJunshuai Date: Fri, 18 Feb 2022 19:01:47 +0800 Subject: [PATCH 08/20] udpate build script to fit "Visual Studio 16 2019" Generator --- BUILDBINARIES_EXAMPLE.bat | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/BUILDBINARIES_EXAMPLE.bat b/BUILDBINARIES_EXAMPLE.bat index 2dd13a542..0752b3b47 100644 --- a/BUILDBINARIES_EXAMPLE.bat +++ b/BUILDBINARIES_EXAMPLE.bat @@ -10,16 +10,15 @@ :: Also see: https://github.com/assimp/assimp/pull/2646 SET SOURCE_DIR=. +SET GENERATOR=Visual Studio 16 2019 -:: For generators see "cmake --help" -SET GENERATOR=Visual Studio 15 2017 - -SET BINARIES_DIR="./BINARIES/Win32" -cmake CMakeLists.txt -G "%GENERATOR%" -S %SOURCE_DIR% -B %BINARIES_DIR% +SET BINARIES_DIR="./build/Win32" +cmake . -G "%GENERATOR%" -A Win32 -S %SOURCE_DIR% -B %BINARIES_DIR% +cmake --build %BINARIES_DIR% --config debug cmake --build %BINARIES_DIR% --config release -SET BINARIES_DIR="./BINARIES/x64" -cmake CMakeLists.txt -G "%GENERATOR% Win64" -S %SOURCE_DIR% -B %BINARIES_DIR% +SET BINARIES_DIR="./build/x64" +cmake . -G "%GENERATOR%" -A x64 -S %SOURCE_DIR% -B %BINARIES_DIR% cmake --build %BINARIES_DIR% --config debug cmake --build %BINARIES_DIR% --config release From ad766cb738fbc899efe64593ff9ec2fd9c0a70a1 Mon Sep 17 00:00:00 2001 From: youkeyao Date: Sun, 20 Feb 2022 17:10:20 +0800 Subject: [PATCH 09/20] update the calculation and orthogonalization for bitangent --- code/PostProcessing/CalcTangentsProcess.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/PostProcessing/CalcTangentsProcess.cpp b/code/PostProcessing/CalcTangentsProcess.cpp index 0ebad91df..b8847e473 100644 --- a/code/PostProcessing/CalcTangentsProcess.cpp +++ b/code/PostProcessing/CalcTangentsProcess.cpp @@ -191,9 +191,9 @@ bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) { tangent.x = (w.x * sy - v.x * ty) * dirCorrection; tangent.y = (w.y * sy - v.y * ty) * dirCorrection; tangent.z = (w.z * sy - v.z * ty) * dirCorrection; - bitangent.x = (w.x * sx - v.x * tx) * dirCorrection; - bitangent.y = (w.y * sx - v.y * tx) * dirCorrection; - bitangent.z = (w.z * sx - v.z * tx) * dirCorrection; + bitangent.x = (- w.x * sx + v.x * tx) * dirCorrection; + bitangent.y = (- w.y * sx + v.y * tx) * dirCorrection; + bitangent.z = (- w.z * sx + v.z * tx) * dirCorrection; // store for every vertex of that face for (unsigned int b = 0; b < face.mNumIndices; ++b) { @@ -201,7 +201,7 @@ bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) { // project tangent and bitangent into the plane formed by the vertex' normal aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]); - aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]); + aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]) - localTangent * (bitangent * localTangent); localTangent.NormalizeSafe(); localBitangent.NormalizeSafe(); From 14874d26f445981d6e1554486a5562ab3a91d11e Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 20 Feb 2022 11:53:26 +0100 Subject: [PATCH 10/20] Fix stat for 32-biut linuxes - Reenable fix to ensure that stat works correctly on 32-bit linuxes again - stat will return 32-bit inodes when checking a file. So when this call will be used on a 64-bit linux this will cause errors like: Error writing to foo: Value too large for defined data type File I/O error: foo - closes https://github.com/assimp/assimp/issues/4390 --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c4e7dbd4..1cdf617d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,6 +243,13 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names") IF( UNIX ) # Use GNUInstallDirs for Unix predefined directories INCLUDE(GNUInstallDirs) + # Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux + IF( ${OPERATING_SYSTEM} MATCHES "Android") + ELSE() + IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux + #ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 ) + ENDIF() + ENDIF() ENDIF() # Grouped compiler settings ######################################## From 96522bc114fc41653250f444dde3843b95ec113c Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 20 Feb 2022 14:06:11 +0100 Subject: [PATCH 11/20] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cdf617d3..3e6c18d91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,7 +247,7 @@ IF( UNIX ) IF( ${OPERATING_SYSTEM} MATCHES "Android") ELSE() IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux - #ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 ) + ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 ) ENDIF() ENDIF() ENDIF() From caaeef2b56288b97813f50b12ed8e9a517fa8b9a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 21 Feb 2022 15:17:23 +0100 Subject: [PATCH 12/20] Update CMakeLists.txt - Show a cmake-warning if assimp_view shall be build for linux / mac --- CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e6c18d91..695f90c31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,12 +134,12 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH OFF ) -IF ( WIN32 ) +IF (WIN32) # Use subset of Windows.h ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN ) IF(MSVC) - OPTION ( ASSIMP_BUILD_ASSIMP_VIEW + OPTION (ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" OFF ) @@ -694,11 +694,13 @@ ENDIF() ADD_SUBDIRECTORY( code/ ) IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) # The viewer for windows only - IF ( WIN32 ) + IF (WIN32) OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" OFF ) IF ( ASSIMP_BUILD_ASSIMP_VIEW ) ADD_SUBDIRECTORY( tools/assimp_view/ ) ENDIF () + ELSE() + MESSAGE("Building Assimp Viewer only supported on Windows.") ENDIF () # The command line tool ADD_SUBDIRECTORY( tools/assimp_cmd/ ) From a6808b868c7e107fe7bcbe922b19e19719cf8524 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 22 Feb 2022 21:07:23 +0100 Subject: [PATCH 13/20] Small code cleanup --- code/AssetLib/glTF/glTFAsset.h | 165 ++++++++++++--------------------- 1 file changed, 57 insertions(+), 108 deletions(-) diff --git a/code/AssetLib/glTF/glTFAsset.h b/code/AssetLib/glTF/glTFAsset.h index 5f5945271..1a42e9020 100644 --- a/code/AssetLib/glTF/glTFAsset.h +++ b/code/AssetLib/glTF/glTFAsset.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2021, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -260,20 +260,9 @@ public: VEC4, MAT2, MAT3, - MAT4 }; - -private: - static const size_t NUM_VALUES = static_cast(MAT4) + 1; - - struct Info { - const char *name; - unsigned int numComponents; + MAT4 }; - template - struct data { static const Info infos[NUM_VALUES]; }; - -public: inline static Value FromString(const char *str) { for (size_t i = 0; i < NUM_VALUES; ++i) { if (strcmp(data<0>::infos[i].name, str) == 0) { @@ -290,40 +279,31 @@ public: inline static unsigned int GetNumComponents(Value type) { return data<0>::infos[static_cast(type)].numComponents; } + +private: + static const size_t NUM_VALUES = static_cast(MAT4) + 1; + struct Info { + const char *name; + unsigned int numComponents; + }; + + template + struct data { + static const Info infos[NUM_VALUES]; + }; }; // must match the order of the AttribTypeTraits::Value enum! template -const AttribType::Info - AttribType::data::infos[AttribType::NUM_VALUES] = { - { "SCALAR", 1 }, { "VEC2", 2 }, { "VEC3", 3 }, { "VEC4", 4 }, { "MAT2", 4 }, { "MAT3", 9 }, { "MAT4", 16 } - }; - -/* - //! A reference to one top-level object, which is valid - //! until the Asset instance is destroyed - template - class Ref - { - std::vector* vector; - unsigned int index; - - public: - Ref() : vector(0), index(0) {} - Ref(std::vector& vec, unsigned int idx) : vector(&vec), index(idx) {} - - inline unsigned int GetIndex() const - { return index; } - - operator bool() const - { return vector != 0; } - - T* operator->() - { return (*vector)[index]; } - - T& operator*() - { return *((*vector)[index]); } - };*/ +const AttribType::Info AttribType::data::infos[AttribType::NUM_VALUES] = { + { "SCALAR", 1 }, + { "VEC2", 2 }, + { "VEC3", 3 }, + { "VEC4", 4 }, + { "MAT2", 4 }, + { "MAT3", 9 }, + { "MAT4", 16 } +}; //! Base class for all glTF top-level objects struct Object { @@ -333,6 +313,7 @@ struct Object { //! Objects marked as special are not exported (used to emulate the binary body buffer) virtual bool IsSpecial() const { return false; } + Object() = default; virtual ~Object() {} //! Maps special IDs to another ID, where needed. Subclasses may override it (statically) @@ -401,21 +382,19 @@ struct Accessor : public Object { return Indexer(*this); } - Accessor() {} + Accessor() = default; void Read(Value &obj, Asset &r); }; //! A buffer points to binary geometry, animation, or skins. struct Buffer : public Object { /********************* Types *********************/ -public: enum Type { Type_arraybuffer, Type_text }; - /// \struct SEncodedRegion - /// Descriptor of encoded region in "bufferView". + /// @brief Descriptor of encoded region in "bufferView". struct SEncodedRegion { const size_t Offset; ///< Offset from begin of "bufferView" to encoded region, in bytes. const size_t EncodedData_Length; ///< Size of encoded region, in bytes. @@ -423,8 +402,7 @@ public: const size_t DecodedData_Length; ///< Size of decoded region, in bytes. const std::string ID; ///< ID of the region. - /// \fn SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID) - /// Constructor. + /// @brief Constructor. /// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes. /// \param [in] pEncodedData_Length - size of encoded region, in bytes. /// \param [in] pDecodedData - pointer to decoded data array. @@ -433,16 +411,13 @@ public: SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID) : Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID) {} - /// \fn ~SEncodedRegion() /// Destructor. ~SEncodedRegion() { delete[] DecodedData; } }; /******************* Variables *******************/ - //std::string uri; //!< The uri of the buffer. Can be a filepath, a data uri, etc. (required) size_t byteLength; //!< The length of the buffer in bytes. (default: 0) - //std::string type; //!< XMLHttpRequest responseType (default: "arraybuffer") Type type; @@ -486,7 +461,6 @@ public: bool LoadFromStream(IOStream &stream, size_t length = 0, size_t baseOffset = 0); - /// \fn void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID) /// Mark region of "bufferView" as encoded. When data is request from such region then "bufferView" use decoded data. /// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes. /// \param [in] pEncodedData_Length - size of encoded region, in bytes. @@ -495,12 +469,10 @@ public: /// \param [in] pID - ID of the region. void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID); - /// \fn void EncodedRegion_SetCurrent(const std::string& pID) /// Select current encoded region by ID. \sa EncodedRegion_Current. /// \param [in] pID - ID of the region. void EncodedRegion_SetCurrent(const std::string &pID); - /// \fn bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count) /// Replace part of buffer data. Pay attention that function work with original array of data (\ref mData) not with encoded regions. /// \param [in] pBufferData_Offset - index of first element in buffer from which new data will be placed. /// \param [in] pBufferData_Count - count of bytes in buffer which will be replaced. @@ -558,37 +530,29 @@ struct Camera : public Object { } ortographic; }; - Camera() {} + Camera() = default; void Read(Value &obj, Asset &r); }; //! Image data used to create a texture. struct Image : public Object { std::string uri; //! The uri of the image, that can be a file path, a data URI, etc.. (required) - Ref bufferView; - std::string mimeType; - int width, height; -private: - std::unique_ptr mData; - size_t mDataLength; - public: Image(); void Read(Value &obj, Asset &r); - inline bool HasData() const { return mDataLength > 0; } - inline size_t GetDataLength() const { return mDataLength; } - inline const uint8_t *GetData() const { return mData.get(); } - inline uint8_t *StealData(); - inline void SetData(uint8_t *data, size_t length, Asset &r); + +private: + std::unique_ptr mData; + size_t mDataLength; }; //! Holds a material property that can be a texture or a color @@ -671,6 +635,7 @@ struct Mesh : public Object { }; #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC + /// \struct SCompression_Open3DGC /// Compression of mesh data using Open3DGC algorithm. struct SCompression_Open3DGC : public SExtension { @@ -703,7 +668,6 @@ struct Mesh : public Object { Mesh() {} - /// \fn ~Mesh() /// Destructor. ~Mesh() { for (std::list::iterator it = Extension.begin(), it_end = Extension.end(); it != it_end; it++) { @@ -711,15 +675,13 @@ struct Mesh : public Object { }; } - /// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root) - /// Get mesh data from JSON-object and place them to root asset. + /// @brief Get mesh data from JSON-object and place them to root asset. /// \param [in] pJSON_Object - reference to pJSON-object from which data are read. /// \param [out] pAsset_Root - reference to root asset where data will be stored. void Read(Value &pJSON_Object, Asset &pAsset_Root); #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - /// \fn void Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root) - /// Decode part of "buffer" which encoded with Open3DGC algorithm. + /// @brief Decode part of "buffer" which encoded with Open3DGC algorithm. /// \param [in] pCompression_Open3DGC - reference to structure which describe encoded region. /// \param [out] pAsset_Root - reference to root assed where data will be stored. void Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DGC, Asset &pAsset_Root); @@ -759,7 +721,7 @@ struct Sampler : public Object { SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required) SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required) - Sampler() {} + Sampler() = default; void Read(Value &obj, Asset &r); void SetDefaults(); }; @@ -767,12 +729,12 @@ struct Sampler : public Object { struct Scene : public Object { std::vector> nodes; - Scene() {} + Scene() = default; void Read(Value &obj, Asset &r); }; struct Shader : public Object { - Shader() {} + Shader() = default; void Read(Value &obj, Asset &r); }; @@ -782,7 +744,7 @@ struct Skin : public Object { std::vector> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin. std::string name; //!< The user-defined name of this object. - Skin() {} + Skin() = default; void Read(Value &obj, Asset &r); }; @@ -796,7 +758,7 @@ struct Technique : public Object { struct Functions { }; - Technique() {} + Technique() = default; void Read(Value &obj, Asset &r); }; @@ -805,13 +767,7 @@ struct Texture : public Object { Ref sampler; //!< The ID of the sampler used by this texture. (required) Ref source; //!< The ID of the image used by this texture. (required) - //TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA) - //TextureFormat internalFormat; //!< The texture's internal format. (default: TextureFormat_RGBA) - - //TextureTarget target; //!< The target that the WebGL texture should be bound to. (default: TextureTarget_TEXTURE_2D) - //TextureType type; //!< Texel datatype. (default: TextureType_UNSIGNED_BYTE) - - Texture() {} + Texture() = default; void Read(Value &obj, Asset &r); }; @@ -826,7 +782,6 @@ struct Light : public Object { }; Type type; - vec4 color; float distance; float constantAttenuation; @@ -835,9 +790,8 @@ struct Light : public Object { float falloffAngle; float falloffExponent; - Light() {} + Light() = default; void Read(Value &obj, Asset &r); - void SetDefaults(); }; @@ -865,15 +819,11 @@ struct Animation : public Object { Ref translation; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors. }; - // AnimChannel Channels[3]; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy. - // AnimParameters Parameters; //!< The samplers that interpolate between the key-frames. - // AnimSampler Samplers[3]; //!< The parameterized inputs representing the key-frame data. - std::vector Channels; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy. AnimParameters Parameters; //!< The samplers that interpolate between the key-frames. std::vector Samplers; //!< The parameterized inputs representing the key-frame data. - Animation() {} + Animation() = default; void Read(Value &obj, Asset &r); }; @@ -963,13 +913,11 @@ struct AssetMetadata { //! Root object for a glTF asset class Asset { - typedef std::gltf_unordered_map IdMap; + using IdMap = std::gltf_unordered_map; template friend class LazyDict; - friend struct Buffer; // To access OpenFile - friend class AssetWriter; private: @@ -1010,12 +958,9 @@ public: LazyDict materials; LazyDict meshes; LazyDict nodes; - //LazyDict programs; LazyDict samplers; LazyDict scenes; - //LazyDict shaders; LazyDict skins; - //LazyDict techniques; LazyDict textures; LazyDict lights; // KHR_materials_common ext @@ -1024,16 +969,20 @@ public: public: Asset(IOSystem *io = 0) : - mIOSystem(io), asset(), accessors(*this, "accessors"), animations(*this, "animations"), buffers(*this, "buffers"), bufferViews(*this, "bufferViews"), cameras(*this, "cameras"), images(*this, "images"), materials(*this, "materials"), meshes(*this, "meshes"), nodes(*this, "nodes") - //, programs (*this, "programs") - , + mIOSystem(io), + asset(), + accessors(*this, "accessors"), + animations(*this, "animations"), + buffers(*this, "buffers"), + bufferViews(*this, "bufferViews"), + cameras(*this, "cameras"), + images(*this, "images"), + materials(*this, "materials"), + meshes(*this, "meshes"), + nodes(*this, "nodes"), samplers(*this, "samplers"), - scenes(*this, "scenes") - //, shaders (*this, "shaders") - , - skins(*this, "skins") - //, techniques (*this, "techniques") - , + scenes(*this, "scenes"), + skins(*this, "skins"), textures(*this, "textures"), lights(*this, "lights", "KHR_materials_common") { memset(&extensionsUsed, 0, sizeof(extensionsUsed)); From aa04ee89f113e2aab9897c473dd24e1d72d51d73 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 22 Feb 2022 21:07:42 +0100 Subject: [PATCH 14/20] Fix init order to fix build --- code/AssetLib/glTF/glTFCommon.h | 2 - code/AssetLib/glTF2/glTF2Asset.h | 76 ++++++----- code/AssetLib/glTF2/glTF2Exporter.cpp | 186 ++++++++++++++------------ 3 files changed, 143 insertions(+), 121 deletions(-) diff --git a/code/AssetLib/glTF/glTFCommon.h b/code/AssetLib/glTF/glTFCommon.h index 78d40ce2c..aec938fee 100644 --- a/code/AssetLib/glTF/glTFCommon.h +++ b/code/AssetLib/glTF/glTFCommon.h @@ -268,8 +268,6 @@ void EncodeBase64(const uint8_t *in, size_t inLength, std::string &out); #define CHECK_EXT(EXT) \ if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true; - - //! Helper struct to represent values that might not be present template struct Nullable { diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index a9b5d442c..120f9a130 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -106,7 +106,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # define gltf_unordered_map tr1::unordered_map # define gltf_unordered_set tr1::unordered_set # else -# define gltf_unordered_map unordered_map +# define gltf_unordered_map unordered_map # define gltf_unordered_set unordered_set # endif #endif @@ -1087,29 +1087,9 @@ class Asset { template friend class LazyDict; - friend struct Buffer; // To access OpenFile - friend class AssetWriter; -private: - IOSystem *mIOSystem; - rapidjson::IRemoteSchemaDocumentProvider *mSchemaDocumentProvider; - - std::string mCurrentAssetDir; - - size_t mSceneLength; - size_t mBodyOffset, mBodyLength; - - std::vector mDicts; - - IdMap mUsedIds; - - Ref mBodyBuffer; - - Asset(Asset &); - Asset &operator=(const Asset &); - public: //! Keeps info about the enabled extensions struct Extensions { @@ -1125,16 +1105,36 @@ public: bool KHR_draco_mesh_compression; bool FB_ngon_encoding; bool KHR_texture_basisu; + + Extensions() : + KHR_materials_pbrSpecularGlossiness(false), + KHR_materials_unlit(false), + KHR_lights_punctual(false), + KHR_texture_transform(false), + KHR_materials_sheen(false), + KHR_materials_clearcoat(false), + KHR_materials_transmission(false), + KHR_materials_volume(false), + KHR_materials_ior(false), + KHR_draco_mesh_compression(false), + FB_ngon_encoding(false), + KHR_texture_basisu(false) { + // empty + } } extensionsUsed; //! Keeps info about the required extensions struct RequiredExtensions { bool KHR_draco_mesh_compression; bool KHR_texture_basisu; + + RequiredExtensions() : KHR_draco_mesh_compression(false), KHR_texture_basisu(false) { + // empty + } } extensionsRequired; AssetMetadata asset; - Value *extras = nullptr; + Value *extras; // Dictionaries for each type of object @@ -1157,9 +1157,10 @@ public: public: Asset(IOSystem *io = nullptr, rapidjson::IRemoteSchemaDocumentProvider *schemaDocumentProvider = nullptr) : - mIOSystem(io), - mSchemaDocumentProvider(schemaDocumentProvider), + extensionsUsed(), + extensionsRequired(), asset(), + extras(nullptr), accessors(*this, "accessors"), animations(*this, "animations"), buffers(*this, "buffers"), @@ -1173,9 +1174,10 @@ public: samplers(*this, "samplers"), scenes(*this, "scenes"), skins(*this, "skins"), - textures(*this, "textures") { - memset(&extensionsUsed, 0, sizeof(extensionsUsed)); - memset(&extensionsRequired, 0, sizeof(extensionsRequired)); + textures(*this, "textures") , + mIOSystem(io), + mSchemaDocumentProvider(schemaDocumentProvider) { + // empty } //! Main function @@ -1192,18 +1194,32 @@ public: Ref GetBodyBuffer() { return mBodyBuffer; } + Asset(Asset &) = delete; + Asset &operator=(const Asset &) = delete; + private: void ReadBinaryHeader(IOStream &stream, std::vector &sceneData); - //! Obtain a JSON document from the stream. - // \param second argument is a buffer used by the document. It must be kept - // alive while the document is in use. + /// Obtain a JSON document from the stream. + /// \param second argument is a buffer used by the document. It must be kept + /// alive while the document is in use. Document ReadDocument(IOStream& stream, bool isBinary, std::vector& sceneData); void ReadExtensionsUsed(Document &doc); void ReadExtensionsRequired(Document &doc); IOStream *OpenFile(const std::string &path, const char *mode, bool absolute = false); + +private: + IOSystem *mIOSystem; + rapidjson::IRemoteSchemaDocumentProvider *mSchemaDocumentProvider; + std::string mCurrentAssetDir; + size_t mSceneLength; + size_t mBodyOffset; + size_t mBodyLength; + std::vector mDicts; + IdMap mUsedIds; + Ref mBodyBuffer; }; inline std::string getContextForErrorMessages(const std::string &id, const std::string &name) { diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index e5c8b4530..87b69c3b3 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -515,72 +515,74 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial &mat, float &prop, const char } void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0) { - if (mat.GetTextureCount(tt) > 0) { - aiString tex; + if (mat.GetTextureCount(tt) == 0) { + return; + } + + aiString tex; - // Read texcoord (UV map index) - mat.Get(AI_MATKEY_UVWSRC(tt, slot), texCoord); + // Read texcoord (UV map index) + mat.Get(AI_MATKEY_UVWSRC(tt, slot), texCoord); - if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) { - std::string path = tex.C_Str(); + if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) { + std::string path = tex.C_Str(); - if (path.size() > 0) { - std::map::iterator it = mTexturesByPath.find(path); - if (it != mTexturesByPath.end()) { - texture = mAsset->textures.Get(it->second); - } + if (path.size() > 0) { + std::map::iterator it = mTexturesByPath.find(path); + if (it != mTexturesByPath.end()) { + texture = mAsset->textures.Get(it->second); + } - bool useBasisUniversal = false; - if (!texture) { - std::string texId = mAsset->FindUniqueID("", "texture"); - texture = mAsset->textures.Create(texId); - mTexturesByPath[path] = texture.GetIndex(); + bool useBasisUniversal = false; + if (!texture) { + std::string texId = mAsset->FindUniqueID("", "texture"); + texture = mAsset->textures.Create(texId); + mTexturesByPath[path] = texture.GetIndex(); - std::string imgId = mAsset->FindUniqueID("", "image"); - texture->source = mAsset->images.Create(imgId); + std::string imgId = mAsset->FindUniqueID("", "image"); + texture->source = mAsset->images.Create(imgId); - const aiTexture *curTex = mScene->GetEmbeddedTexture(path.c_str()); - if (curTex != nullptr) { // embedded - texture->source->name = curTex->mFilename.C_Str(); + const aiTexture *curTex = mScene->GetEmbeddedTexture(path.c_str()); + if (curTex != nullptr) { // embedded + texture->source->name = curTex->mFilename.C_Str(); - //basisu: embedded ktx2, bu - if (curTex->achFormatHint[0]) { - std::string mimeType = "image/"; - if (memcmp(curTex->achFormatHint, "jpg", 3) == 0) - mimeType += "jpeg"; - else if (memcmp(curTex->achFormatHint, "ktx", 3) == 0) { - useBasisUniversal = true; - mimeType += "ktx"; - } else if (memcmp(curTex->achFormatHint, "kx2", 3) == 0) { - useBasisUniversal = true; - mimeType += "ktx2"; - } else if (memcmp(curTex->achFormatHint, "bu", 2) == 0) { - useBasisUniversal = true; - mimeType += "basis"; - } else - mimeType += curTex->achFormatHint; - texture->source->mimeType = mimeType; - } - - // The asset has its own buffer, see Image::SetData - //basisu: "image/ktx2", "image/basis" as is - texture->source->SetData(reinterpret_cast(curTex->pcData), curTex->mWidth, *mAsset); - } else { - texture->source->uri = path; - if (texture->source->uri.find(".ktx") != std::string::npos || - texture->source->uri.find(".basis") != std::string::npos) { + //basisu: embedded ktx2, bu + if (curTex->achFormatHint[0]) { + std::string mimeType = "image/"; + if (memcmp(curTex->achFormatHint, "jpg", 3) == 0) + mimeType += "jpeg"; + else if (memcmp(curTex->achFormatHint, "ktx", 3) == 0) { useBasisUniversal = true; - } + mimeType += "ktx"; + } else if (memcmp(curTex->achFormatHint, "kx2", 3) == 0) { + useBasisUniversal = true; + mimeType += "ktx2"; + } else if (memcmp(curTex->achFormatHint, "bu", 2) == 0) { + useBasisUniversal = true; + mimeType += "basis"; + } else + mimeType += curTex->achFormatHint; + texture->source->mimeType = mimeType; } - //basisu - if (useBasisUniversal) { - mAsset->extensionsUsed.KHR_texture_basisu = true; - mAsset->extensionsRequired.KHR_texture_basisu = true; + // The asset has its own buffer, see Image::SetData + //basisu: "image/ktx2", "image/basis" as is + texture->source->SetData(reinterpret_cast(curTex->pcData), curTex->mWidth, *mAsset); + } else { + texture->source->uri = path; + if (texture->source->uri.find(".ktx") != std::string::npos || + texture->source->uri.find(".basis") != std::string::npos) { + useBasisUniversal = true; } - - GetTexSampler(mat, texture, tt, slot); } + + //basisu + if (useBasisUniversal) { + mAsset->extensionsUsed.KHR_texture_basisu = true; + mAsset->extensionsRequired.KHR_texture_basisu = true; + } + + GetTexSampler(mat, texture, tt, slot); } } } @@ -588,12 +590,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref &texture, unsi void glTF2Exporter::GetMatTex(const aiMaterial &mat, TextureInfo &prop, aiTextureType tt, unsigned int slot = 0) { Ref &texture = prop.texture; - GetMatTex(mat, texture, prop.texCoord, tt, slot); - - //if (texture) { - // GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); - //} } void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, aiTextureType tt, unsigned int slot = 0) { @@ -681,12 +678,14 @@ bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlo bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen) { // Return true if got any valid Sheen properties or textures - if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS) + if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS) { return false; + } // Default Sheen color factor {0,0,0} disables Sheen, so do not export - if (sheen.sheenColorFactor == defaultSheenFactor) + if (sheen.sheenColorFactor == defaultSheenFactor) { return false; + } mat.Get(AI_MATKEY_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor); @@ -781,9 +780,7 @@ void glTF2Exporter::ExportMaterials() { aiColor4D specularColor; ai_real shininess; - if ( - mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && - mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) { + if (mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) { // convert specular color to luminance float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f; //normalize shininess (assuming max is 1000) with an inverse exponentional curve @@ -916,7 +913,8 @@ Ref FindSkeletonRootJoint(Ref &skinRef) { return parentNodeRef; } -void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref &meshRef, Ref &bufferRef, Ref &skinRef, std::vector &inverseBindMatricesData) { +void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref &meshRef, Ref &bufferRef, Ref &skinRef, + std::vector &inverseBindMatricesData) { if (aimesh->mNumBones < 1) { return; } @@ -986,7 +984,8 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref &meshRef, Refprimitives.back(); - Ref vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); + Ref vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, + vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); if (vertexJointAccessor) { size_t offset = vertexJointAccessor->bufferView->byteOffset; size_t bytesLen = vertexJointAccessor->bufferView->byteLength; @@ -1069,8 +1068,11 @@ void glTF2Exporter::ExportMeshes() { p.ngonEncoded = (aim->mPrimitiveTypes & aiPrimitiveType_NGONEncodingFlag) != 0; /******************* Vertices ********************/ - Ref v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); - if (v) p.attributes.position.push_back(v); + Ref v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, + AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); + if (v) { + p.attributes.position.push_back(v); + } /******************** Normals ********************/ // Normalize all normals as the validator can emit a warning otherwise @@ -1080,13 +1082,17 @@ void glTF2Exporter::ExportMeshes() { } } - Ref n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); - if (n) p.attributes.normal.push_back(n); + Ref n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, + AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); + if (n) { + p.attributes.normal.push_back(n); + } /************** Texture coordinates **************/ for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (!aim->HasTextureCoords(i)) + if (!aim->HasTextureCoords(i)) { continue; + } // Flip UV y coords if (aim->mNumUVComponents[i] > 1) { @@ -1098,16 +1104,21 @@ void glTF2Exporter::ExportMeshes() { if (aim->mNumUVComponents[i] > 0) { AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3; - Ref tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); - if (tc) p.attributes.texcoord.push_back(tc); + Ref tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], + AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); + if (tc) { + p.attributes.texcoord.push_back(tc); + } } } /*************** Vertex colors ****************/ for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) { - Ref c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel], AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); - if (c) + Ref c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel], + AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); + if (c) { p.attributes.color.push_back(c); + } } /*************** Vertices indices ****************/ @@ -1121,7 +1132,8 @@ void glTF2Exporter::ExportMeshes() { } } - p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER); + p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, + ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER); } switch (aim->mPrimitiveTypes) { @@ -1136,6 +1148,7 @@ void glTF2Exporter::ExportMeshes() { break; default: // aiPrimitiveType_TRIANGLE p.mode = PrimitiveMode_TRIANGLES; + break; } /*************** Skins ****************/ @@ -1155,8 +1168,9 @@ void glTF2Exporter::ExportMeshes() { p.targets.resize(aim->mNumAnimMeshes); for (unsigned int am = 0; am < aim->mNumAnimMeshes; ++am) { aiAnimMesh *pAnimMesh = aim->mAnimMeshes[am]; - if (bExportTargetNames) - m->targetNames.push_back(pAnimMesh->mName.data); + if (bExportTargetNames) { + m->targetNames.emplace_back(pAnimMesh->mName.data); + } // position if (pAnimMesh->HasPositions()) { // NOTE: in gltf it is the diff stored @@ -1319,12 +1333,12 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode *n) { } for (unsigned int i = 0; i < n->mNumMeshes; ++i) { - node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i])); + node->meshes.emplace_back(mAsset->meshes.Get(n->mMeshes[i])); } for (unsigned int i = 0; i < n->mNumChildren; ++i) { unsigned int idx = ExportNode(n->mChildren[i], node); - node->children.push_back(mAsset->nodes.Get(idx)); + node->children.emplace_back(mAsset->nodes.Get(idx)); } return node.GetIndex(); @@ -1366,12 +1380,12 @@ unsigned int glTF2Exporter::ExportNode(const aiNode *n, Ref &parent) { } for (unsigned int i = 0; i < n->mNumMeshes; ++i) { - node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i])); + node->meshes.emplace_back(mAsset->meshes.Get(n->mMeshes[i])); } for (unsigned int i = 0; i < n->mNumChildren; ++i) { unsigned int idx = ExportNode(n->mChildren[i], node); - node->children.push_back(mAsset->nodes.Get(idx)); + node->children.emplace_back(mAsset->nodes.Get(idx)); } return node.GetIndex(); @@ -1386,7 +1400,7 @@ void glTF2Exporter::ExportScene() { // root node will be the first one exported (idx 0) if (mAsset->nodes.Size() > 0) { - scene->nodes.push_back(mAsset->nodes.Get(0u)); + scene->nodes.emplace_back(mAsset->nodes.Get(0u)); } // set as the default scene @@ -1521,12 +1535,6 @@ void glTF2Exporter::ExportAnimations() { AddSampler(animRef, animNode, scaleSampler, AnimationPath_SCALE); } } - - // Assimp documentation states this is not used (not implemented) - // for (unsigned int channelIndex = 0; channelIndex < anim->mNumMeshChannels; ++channelIndex) { - // const aiMeshAnim* meshChannel = anim->mMeshChannels[channelIndex]; - // } - } // End: for-loop mNumAnimations } From 4ddacdb5df027759267f452a2f365d5385805fc2 Mon Sep 17 00:00:00 2001 From: Terence Russell Date: Tue, 22 Feb 2022 17:55:41 -0700 Subject: [PATCH 15/20] Expose the original OBJ illum model as a material property. --- code/AssetLib/Obj/ObjFileImporter.cpp | 3 +++ include/assimp/ObjMaterial.h | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/code/AssetLib/Obj/ObjFileImporter.cpp b/code/AssetLib/Obj/ObjFileImporter.cpp index 6dd26956e..68fdb2172 100644 --- a/code/AssetLib/Obj/ObjFileImporter.cpp +++ b/code/AssetLib/Obj/ObjFileImporter.cpp @@ -605,6 +605,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc mat->AddProperty(&sm, 1, AI_MATKEY_SHADING_MODEL); + // Preserve the original illum value + mat->AddProperty(&pCurrentMaterial->illumination_model, 1, AI_MATKEY_OBJ_ILLUM); + // Adding material colors mat->AddProperty(&pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT); mat->AddProperty(&pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE); diff --git a/include/assimp/ObjMaterial.h b/include/assimp/ObjMaterial.h index 39894a696..bba207638 100644 --- a/include/assimp/ObjMaterial.h +++ b/include/assimp/ObjMaterial.h @@ -53,6 +53,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +// --------------------------------------------------------------------------- + +// the original illum property +#define AI_MATKEY_OBJ_ILLUM "$mat.illum", 0, 0 + +// --------------------------------------------------------------------------- + // --------------------------------------------------------------------------- // Pure key names for all obj texture-related properties //! @cond MATS_DOC_FULL From 6f31254ae1d7f0058395edd84d13f6ce8ffcd110 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 23 Feb 2022 20:57:15 +0100 Subject: [PATCH 16/20] Ensure dictionary for LazyDics is created before adding content to it --- code/AssetLib/glTF2/glTF2Asset.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index b2d5498cf..c597fc951 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -1090,6 +1090,8 @@ class Asset { friend struct Buffer; // To access OpenFile friend class AssetWriter; + std::vector mDicts; + public: //! Keeps info about the enabled extensions struct Extensions { @@ -1156,7 +1158,8 @@ public: Ref scene; public: - Asset(IOSystem *io = nullptr, rapidjson::IRemoteSchemaDocumentProvider *schemaDocumentProvider = nullptr) : + Asset(IOSystem *io = nullptr, rapidjson::IRemoteSchemaDocumentProvider *schemaDocumentProvider = nullptr) : + mDicts(), extensionsUsed(), extensionsRequired(), asset(), @@ -1217,7 +1220,6 @@ private: size_t mSceneLength; size_t mBodyOffset; size_t mBodyLength; - std::vector mDicts; IdMap mUsedIds; Ref mBodyBuffer; }; From cf966391190a5c6b00feeb0f3250202c3d01ff00 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 24 Feb 2022 16:49:35 +0100 Subject: [PATCH 17/20] Fix possible negative array access - Return when the calculated offset gets negative - closes https://github.com/assimp/assimp/issues/4414 --- include/assimp/Hash.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/assimp/Hash.h b/include/assimp/Hash.h index 1f2baedac..1a5d1f08d 100644 --- a/include/assimp/Hash.h +++ b/include/assimp/Hash.h @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2022, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -96,7 +95,11 @@ int rem; switch (rem) { case 3: hash += get16bits (data); hash ^= hash << 16; - hash ^= data[sizeof (uint16_t)] << 18; + size_t offset = static_cast(sizeof(uint16_t)); + if (offset < 0) { + return 0; + } + hash ^= data[offset] << 18; hash += hash >> 11; break; case 2: hash += get16bits (data); From 0dc24ab3a747ca97a23bec6eb8d0123d2b5f9c19 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 24 Feb 2022 17:04:39 +0100 Subject: [PATCH 18/20] Fix declaration of offset --- include/assimp/Hash.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/assimp/Hash.h b/include/assimp/Hash.h index 1a5d1f08d..5a02f5f31 100644 --- a/include/assimp/Hash.h +++ b/include/assimp/Hash.h @@ -75,7 +75,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) { uint32_t tmp; int rem; - +size_t offset; + if (!data) return 0; if (!len)len = (uint32_t)::strlen(data); @@ -95,7 +96,7 @@ int rem; switch (rem) { case 3: hash += get16bits (data); hash ^= hash << 16; - size_t offset = static_cast(sizeof(uint16_t)); + offset = static_cast(sizeof(uint16_t)); if (offset < 0) { return 0; } From c73ff82fc496d316512f9db0dd753fcb1eb65f81 Mon Sep 17 00:00:00 2001 From: sola Date: Fri, 25 Feb 2022 19:58:44 +0800 Subject: [PATCH 19/20] FBXConvert::ConvertMeshMultiMaterial: allocate memory using variable count_vertices --- code/AssetLib/FBX/FBXConverter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index 39db79a3e..32872108b 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -1267,7 +1267,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co const std::vector &normals = mesh.GetNormals(); if (normals.size()) { ai_assert(normals.size() == vertices.size()); - out_mesh->mNormals = new aiVector3D[vertices.size()]; + out_mesh->mNormals = new aiVector3D[count_vertices]; } // allocate tangents, binormals. @@ -1295,8 +1295,8 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co ai_assert(tangents.size() == vertices.size()); ai_assert(binormals->size() == vertices.size()); - out_mesh->mTangents = new aiVector3D[vertices.size()]; - out_mesh->mBitangents = new aiVector3D[vertices.size()]; + out_mesh->mTangents = new aiVector3D[count_vertices]; + out_mesh->mBitangents = new aiVector3D[count_vertices]; } } @@ -1308,7 +1308,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co break; } - out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()]; + out_mesh->mTextureCoords[i] = new aiVector3D[count_vertices]; out_mesh->mNumUVComponents[i] = 2; } @@ -1320,7 +1320,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co break; } - out_mesh->mColors[i] = new aiColor4D[vertices.size()]; + out_mesh->mColors[i] = new aiColor4D[count_vertices]; } unsigned int cursor = 0, in_cursor = 0; From 8e59287b9464ad7352ccaf206da34f9e20dcd0b7 Mon Sep 17 00:00:00 2001 From: Rahul Sheth Date: Fri, 25 Feb 2022 13:52:18 -0600 Subject: [PATCH 20/20] Update version of Hunter to v0.24.0 that supports VS 2022 --- .github/workflows/ccpp.yml | 9 ++++----- CMakeLists.txt | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index cef3fd4c7..510ae8e7f 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -13,8 +13,7 @@ jobs: strategy: fail-fast: false matrix: - #name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++, ubuntu-gcc-hunter, macos-clang-hunter, windows-msvc-hunter] - name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++, ubuntu-gcc-hunter, macos-clang-hunter] + name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++, ubuntu-gcc-hunter, macos-clang-hunter, windows-msvc-hunter] # For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux. include: - name: windows-latest-cl.exe @@ -39,9 +38,9 @@ jobs: - name: macos-clang-hunter os: macos-latest toolchain: ninja-clang-cxx17-fpic - #- name: windows-msvc-hunter - # os: windows-latest - # toolchain: ninja-vs-win64-cxx17 + - name: windows-msvc-hunter + os: windows-latest + toolchain: ninja-vs-win64-cxx17 steps: - uses: actions/checkout@v2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 695f90c31..5cbbfef2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,8 +49,8 @@ option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF) IF(ASSIMP_HUNTER_ENABLED) include("cmake-modules/HunterGate.cmake") HunterGate( - URL "https://github.com/cpp-pm/hunter/archive/v0.23.311.tar.gz" - SHA1 "1a82b9b73055879181cb1466b2ab5d48ee8ae410" + URL "https://github.com/cpp-pm/hunter/archive/v0.24.0.tar.gz" + SHA1 "a3d7f4372b1dcd52faa6ff4a3bd5358e1d0e5efd" ) add_definitions(-DASSIMP_USE_HUNTER)