From 8fcc65a8af222f73ca6fbe5ed28054620d242a84 Mon Sep 17 00:00:00 2001 From: fvbj Date: Fri, 22 Sep 2023 23:10:39 +0200 Subject: [PATCH 1/6] Extension of data export to GLB/GLTF format Allows to export unlimited (more than 4) bones per vertex Use JOINTS_1,2,.. and WEIGHTS_1,2,... Added AI_CONFIG_EXPORT_GLTF_UNLIMITED_SKINNING_BONES_PER_VERTEX flag --- code/AssetLib/glTF2/glTF2Exporter.cpp | 171 +++++++++++--------- include/assimp/config.h.in | 13 ++ test/models/glTF2/simple_skin/quad_skin.glb | Bin 0 -> 10048 bytes test/unit/utglTF2ImportExport.cpp | 139 ++++++++++++++++ 4 files changed, 251 insertions(+), 72 deletions(-) create mode 100644 test/models/glTF2/simple_skin/quad_skin.glb diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index d6f778fbe..614ce763c 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -172,22 +172,6 @@ static void IdentityMatrix4(mat4 &o) { o[15] = 1; } -static bool IsBoneWeightFitted(vec4 &weight) { - return weight[0] + weight[1] + weight[2] + weight[3] >= 1.f; -} - -static int FitBoneWeight(vec4 &weight, float value) { - int i = 0; - for (; i < 4; ++i) { - if (weight[i] < value) { - weight[i] = value; - return i; - } - } - - return -1; -} - template void SetAccessorRange(Ref acc, void *data, size_t count, unsigned int numCompsIn, unsigned int numCompsOut) { @@ -1009,23 +993,29 @@ Ref FindSkeletonRootJoint(Ref &skinRef) { return parentNodeRef; } +struct boneIndexWeightPair { + unsigned int indexJoint; + float weight; + bool operator()(boneIndexWeightPair &a, boneIndexWeightPair &b) { + return a.weight > b.weight; + } +}; + void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref &meshRef, Ref &bufferRef, Ref &skinRef, - std::vector &inverseBindMatricesData) { + std::vector &inverseBindMatricesData, bool unlimitedBonesPerVertex) { if (aimesh->mNumBones < 1) { return; } // Store the vertex joint and weight data. const size_t NumVerts(aimesh->mNumVertices); - vec4 *vertexJointData = new vec4[NumVerts]; - vec4 *vertexWeightData = new vec4[NumVerts]; int *jointsPerVertex = new int[NumVerts]; + std::vector> allVerticesPairs; + int maxJointsPerVertex = 0; for (size_t i = 0; i < NumVerts; ++i) { jointsPerVertex[i] = 0; - for (size_t j = 0; j < 4; ++j) { - vertexJointData[i][j] = 0; - vertexWeightData[i][j] = 0; - } + std::vector vertexPair; + allVerticesPairs.push_back(vertexPair); } for (unsigned int idx_bone = 0; idx_bone < aimesh->mNumBones; ++idx_bone) { @@ -1055,61 +1045,88 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref &meshRef, Ref(inverseBindMatricesData.size() - 1); } - // aib->mWeights =====> vertexWeightData - for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; ++idx_weights) { + // aib->mWeights =====> temp pairs data + for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; + ++idx_weights) { unsigned int vertexId = aib->mWeights[idx_weights].mVertexId; float vertWeight = aib->mWeights[idx_weights].mWeight; - - // A vertex can only have at most four joint weights, which ideally sum up to 1 - if (IsBoneWeightFitted(vertexWeightData[vertexId])) { - continue; - } - if (jointsPerVertex[vertexId] > 3) { - int boneIndexFitted = FitBoneWeight(vertexWeightData[vertexId], vertWeight); - if (boneIndexFitted != -1) { - vertexJointData[vertexId][boneIndexFitted] = static_cast(jointNamesIndex); - } - } else { - vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast(jointNamesIndex); - vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight; - - jointsPerVertex[vertexId] += 1; - } + allVerticesPairs[vertexId].push_back({jointNamesIndex, vertWeight}); + jointsPerVertex[vertexId] += 1; + maxJointsPerVertex = + std::max(maxJointsPerVertex, jointsPerVertex[vertexId]); } - } // End: for-loop mNumMeshes - Mesh::Primitive &p = meshRef->primitives.back(); - 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; - unsigned int s_bytesPerComp = ComponentTypeSize(ComponentType_UNSIGNED_SHORT); - unsigned int bytesPerComp = ComponentTypeSize(vertexJointAccessor->componentType); - size_t s_bytesLen = bytesLen * s_bytesPerComp / bytesPerComp; - Ref buf = vertexJointAccessor->bufferView->buffer; - uint8_t *arrys = new uint8_t[bytesLen]; - unsigned int i = 0; - for (unsigned int j = 0; j < bytesLen; j += bytesPerComp) { - size_t len_p = offset + j; - float f_value = *(float *)&buf->GetPointer()[len_p]; - unsigned short c = static_cast(f_value); - memcpy(&arrys[i * s_bytesPerComp], &c, s_bytesPerComp); - ++i; - } - buf->ReplaceData_joint(offset, bytesLen, arrys, bytesLen); - vertexJointAccessor->componentType = ComponentType_UNSIGNED_SHORT; - vertexJointAccessor->bufferView->byteLength = s_bytesLen; - - p.attributes.joint.push_back(vertexJointAccessor); - delete[] arrys; + if (!unlimitedBonesPerVertex){ + // skinning limited only for 4 bones per vertex, default + maxJointsPerVertex = 4; } - Ref vertexWeightAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, - vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); - if (vertexWeightAccessor) { - p.attributes.weight.push_back(vertexWeightAccessor); + // temp pairs data =====> vertexWeightData + size_t numGroups = (maxJointsPerVertex - 1) / 4 + 1; + vec4 *vertexJointData = new vec4[NumVerts * numGroups]; + vec4 *vertexWeightData = new vec4[NumVerts * numGroups]; + for (size_t indexVertex = 0; indexVertex < NumVerts; ++indexVertex) { + // order pairs by weight for each vertex + std::sort(allVerticesPairs[indexVertex].begin(), + allVerticesPairs[indexVertex].end(), + boneIndexWeightPair()); + for (size_t indexGroup = 0; indexGroup < numGroups; ++indexGroup) { + for (size_t indexJoint = 0; indexJoint < 4; ++indexJoint) { + size_t indexBone = indexGroup * 4 + indexJoint; + size_t indexData = indexVertex + NumVerts * indexGroup; + if (indexBone >= allVerticesPairs[indexVertex].size()) { + vertexJointData[indexData][indexJoint] = 0.f; + vertexWeightData[indexData][indexJoint] = 0.f; + } else { + vertexJointData[indexData][indexJoint] = + static_cast( + allVerticesPairs[indexVertex][indexBone].indexJoint); + vertexWeightData[indexData][indexJoint] = + allVerticesPairs[indexVertex][indexBone].weight; + } + } + } + } + + for (size_t idx_group = 0; idx_group < numGroups; ++idx_group) { + Mesh::Primitive &p = meshRef->primitives.back(); + Ref vertexJointAccessor = ExportData( + mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, + vertexJointData + idx_group * NumVerts, + AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); + if (vertexJointAccessor) { + size_t offset = vertexJointAccessor->bufferView->byteOffset; + size_t bytesLen = vertexJointAccessor->bufferView->byteLength; + unsigned int s_bytesPerComp = + ComponentTypeSize(ComponentType_UNSIGNED_SHORT); + unsigned int bytesPerComp = + ComponentTypeSize(vertexJointAccessor->componentType); + size_t s_bytesLen = bytesLen * s_bytesPerComp / bytesPerComp; + Ref buf = vertexJointAccessor->bufferView->buffer; + uint8_t *arrys = new uint8_t[bytesLen]; + unsigned int i = 0; + for (unsigned int j = 0; j < bytesLen; j += bytesPerComp) { + size_t len_p = offset + j; + float f_value = *(float *)&buf->GetPointer()[len_p]; + unsigned short c = static_cast(f_value); + memcpy(&arrys[i * s_bytesPerComp], &c, s_bytesPerComp); + ++i; + } + buf->ReplaceData_joint(offset, bytesLen, arrys, bytesLen); + vertexJointAccessor->componentType = ComponentType_UNSIGNED_SHORT; + vertexJointAccessor->bufferView->byteLength = s_bytesLen; + + p.attributes.joint.push_back(vertexJointAccessor); + delete[] arrys; + } + Ref vertexWeightAccessor = ExportData( + mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, + vertexWeightData + idx_group * NumVerts, + AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); + if (vertexWeightAccessor) { + p.attributes.weight.push_back(vertexWeightAccessor); + } } delete[] jointsPerVertex; delete[] vertexWeightData; @@ -1247,9 +1264,19 @@ void glTF2Exporter::ExportMeshes() { break; } +// /*************** Skins ****************/ +// if (aim->HasBones()) { +// ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData); +// } /*************** Skins ****************/ if (aim->HasBones()) { - ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData); + bool unlimitedBonesPerVertex = + this->mProperties->HasPropertyBool( + AI_CONFIG_EXPORT_GLTF_UNLIMITED_SKINNING_BONES_PER_VERTEX) && + this->mProperties->GetPropertyBool( + AI_CONFIG_EXPORT_GLTF_UNLIMITED_SKINNING_BONES_PER_VERTEX); + ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData, + unlimitedBonesPerVertex); } /*************** Targets for blendshapes ****************/ diff --git a/include/assimp/config.h.in b/include/assimp/config.h.in index 97551e602..cb46d8057 100644 --- a/include/assimp/config.h.in +++ b/include/assimp/config.h.in @@ -1085,6 +1085,19 @@ enum aiComponent */ #define AI_CONFIG_USE_GLTF_PBR_SPECULAR_GLOSSINESS "USE_GLTF_PBR_SPECULAR_GLOSSINESS" +/** @brief Specifies whether to apply a limit on the number of four bones per vertex in skinning + * + * When this flag is not defined, all bone weights and indices are limited to a + * maximum of four bones for each vertex (attributes JOINT_0 and WEIGHT_0 only). + * By enabling this flag, the number of bones per vertex is unlimited. + * In both cases, indices and bone weights are sorted by weight in descending order. + * In the case of the limit of up to four bones, a maximum of the four largest values are exported. + * Weights are not normalized. + * Property type: Bool. Default value: false. + */ +#define AI_CONFIG_EXPORT_GLTF_UNLIMITED_SKINNING_BONES_PER_VERTEX \ + "USE_UNLIMITED_BONES_PER VERTEX" + /** * @brief Specifies the blob name, assimp uses for exporting. * diff --git a/test/models/glTF2/simple_skin/quad_skin.glb b/test/models/glTF2/simple_skin/quad_skin.glb new file mode 100644 index 0000000000000000000000000000000000000000..407cebc76b56e6ebd9732447e0a75f072326746b GIT binary patch literal 10048 zcmeHN%Woq|8TTv$3pa$gamlvCOLVNN>Zj4 z?2JZ15!(L%BqT0ekoGXF#7klhphZIBz=0D7Rvb7iLM%5v)ZJNou2!pk_4Bpbx>c*awB6Z!Z27}skXVh!)`K7(hW*HDSfb7>+d2xO zAoi1fjF!$Ih?Z7p{~?y-b!OvEFV2l%MtDY}$&rroJf)?lm||K5%Pz3#g<#9QWtv5g@-(!a zH}Axr#+?5*FlQ;|=YS)6CaCJVU_weqOT)PGxCxfI8q+6*a3wd&IG`_`SjJU6JFcS4 zF!@0mNu#X8aR+q*wpI=HpyJ=DgXgs?Fv3aw|fP;=Q3H^p6%Ltf^^E{S&j9s0PG4(hTBob)0}AX zT*vi@QqOfYSAsi^kzA+5dzvY!B*#EyT$T<~uIs_FAq+)NVJ1jtW=3n#J;Nz;1?1;) z%GiQ&fFcrUXmquNMkyhM2X8l~x$xOJ5610f>*w#! zDHAoh{co)7OzntD ztHFh2lYUAR&L$4$B@N^wi`f$9ocQq(QLW-5(+*15 zwH2Jl)z{W+hRRg`#@TI}wnjek+lF;3IP^!|WFyafkunVS;*B8jyWMbqt3NtAj*#n8 z3clwLgVlbwAFuiQY2tm4)xD{7)4&bPZ-GA`$DD&G7K1A|Az9>T6}VbtIK5za9Aq|= zci-*$5oPCtIP8T<_#p4?^$$Q3q&A*T8F?5Tgh<%a4nIlaaBq}Q^|5ugv)$flcQ#W) z+U#s?tgORaZENTDE32K()~#J;H6W+e&U$By$_P9!b=sRd+f+f~lvlXbK!DFH!fGIf zedBif#XH$Jh_0w%Ae5x2VI&99_ld*^m`_o-)$b>pL=IA~z3?hk@E35jkC1hj{nqi)w~B=IP)3%y(^GJAIH`|{Vo~$yqOFQ318Gxv+bh9(A%1M`YuZxndQ(ftr zYI^E;6-p zt1Diwn&QPjVT((xyb6l9ILG{d9^TREYI?9X{1$ylfD^X=Q8El&81Cb{jr^Q5Kk>w0 zfYbrlQ|F&4GPd>2ei$XxaoM?I7}4h;!A%_WZqO-cdf3Z(x-J0(Q73=8UaQ?~Z{iD+ z)3@keyY)$l_l;{P-oe% z*RT+MD?=B(KZ5(CxUZ!pdS1`V)Jyf}@xJ_e{?D(r{`tr4)~nzDTl39FPn(~9=X #include +#include #include #include #include @@ -504,6 +505,144 @@ TEST_F(utglTF2ImportExport, bug_import_simple_skin) { EXPECT_NE(nullptr, scene); } +bool checkSkinnedScene(const aiScene *scene){ + float eps = 0.001; + bool result = true; + EXPECT_EQ(scene->mNumMeshes, 1u); + EXPECT_EQ(scene->mMeshes[0]->mNumBones, 10u); + EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[0].x - -1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[0].y - -1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[0].z - 0), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[1].x - 1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[1].y - -1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[1].z - 0), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[2].x - 1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[2].y - 1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[2].z - 0), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].x - -1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].y - 1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].z - 0), eps); + + uint numWeights[] = {4u, 4u, 4u, 4u, 2u , 1u, 1u, 2u, 1u, 1u}; + float weights[10][4] = {{0.207, 0.291, 0.057, 0.303}, + {0.113, 0.243, 0.499, 0.251}, + {0.005, 0.010, 0.041, 0.093}, + {0.090, 0.234, 0.404, 0.243}, + {0.090, 0.222, 0.000, 0.000}, + {0.216, 0.000, 0.000, 0.000}, + {0.058, 0.000, 0.000, 0.000}, + {0.086, 0.000, 0.000, 0.111}, + {0.088, 0.000, 0.000, 0.000}, + {0.049, 0.000, 0.000, 0.000}}; + for (size_t boneIndex = 0; boneIndex < 10u; ++boneIndex) { + EXPECT_EQ(scene->mMeshes[0]->mBones[boneIndex]->mNumWeights, numWeights[boneIndex]); + std::map map; + for (size_t jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex){ + auto key = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mVertexId; + auto weight = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mWeight; + map[key] = weight; + } + + for (size_t jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex) { + auto weight = map[jointIndex]; + EXPECT_LT(abs(ai_real(weight) - ai_real(weights[boneIndex][jointIndex])), 0.002); + } + + } + + return result; +} + +void checkSkinnedSceneLimited(const aiScene *scene){ + float eps = 0.001; + EXPECT_EQ(scene->mNumMeshes, 1u); + EXPECT_EQ(scene->mMeshes[0]->mNumBones, 10u); + EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[0].x - -1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[0].y - -1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[0].z - 0), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[1].x - 1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[1].y - -1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[1].z - 0), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[2].x - 1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[2].y - 1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[2].z - 0), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].x - -1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].y - 1), eps); + EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].z - 0), eps); + + uint numWeights[] = {4u, 4u, 1u, 4u, 1u , 1u, 1u, 1u, 1u, 1u}; + float weights[10][4] = {{0.207, 0.291, 0.057, 0.303}, + {0.113, 0.243, 0.499, 0.251}, + {0.000, 0.000, 0.041, 0.000}, + {0.090, 0.234, 0.404, 0.243}, + {0.000, 0.222, 0.000, 0.000}, + {0.216, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.111}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}}; + for (size_t boneIndex = 0; boneIndex < 10u; ++boneIndex) { + EXPECT_EQ(scene->mMeshes[0]->mBones[boneIndex]->mNumWeights, numWeights[boneIndex]); + std::map map; + for (size_t jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex){ + auto key = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mVertexId; + auto weight = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mWeight; + map[key] = weight; + } + for (size_t jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex) { + auto weight = map[jointIndex]; + EXPECT_LT(std::abs(ai_real(weight) - ai_real(weights[boneIndex][jointIndex])), 0.002); + } + } +} + +TEST_F(utglTF2ImportExport, bug_import_simple_skin2) { + Assimp::Importer importer; + Assimp::Exporter exporter; + const aiScene *scene = importer.ReadFile( + ASSIMP_TEST_MODELS_DIR "/glTF2/simple_skin/quad_skin.glb", + aiProcess_ValidateDataStructure); + checkSkinnedScene(scene); + + ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", + ASSIMP_TEST_MODELS_DIR "/glTF2/simple_skin/quad_four_out.glb")); + ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "gltf2", + ASSIMP_TEST_MODELS_DIR "/glTF2/simple_skin/quad_four_out.gltf")); + + // enable more than four bones per vertex + Assimp::ExportProperties properties = Assimp::ExportProperties(); + properties.SetPropertyBool( + AI_CONFIG_EXPORT_GLTF_UNLIMITED_SKINNING_BONES_PER_VERTEX, true); + ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", + ASSIMP_TEST_MODELS_DIR "/glTF2/simple_skin/quad_all_out.glb", 0u, &properties)); + ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "gltf2", + ASSIMP_TEST_MODELS_DIR "/glTF2/simple_skin/quad_all_out.gltf", 0u, &properties)); + + // check skinning data of both exported files for limited number bones per vertex + const aiScene *limitedSceneImported = importer.ReadFile( + ASSIMP_TEST_MODELS_DIR "/glTF2/simple_skin/quad_four_out.gltf", + aiProcess_ValidateDataStructure); + checkSkinnedSceneLimited(limitedSceneImported); + limitedSceneImported = importer.ReadFile( + ASSIMP_TEST_MODELS_DIR "/glTF2/simple_skin/quad_four_out.glb", + aiProcess_ValidateDataStructure); + checkSkinnedSceneLimited(limitedSceneImported); + + // check skinning data of both exported files for unlimited number bones per vertex + const aiScene *sceneImported = importer.ReadFile( + ASSIMP_TEST_MODELS_DIR "/glTF2/simple_skin/quad_all_out.gltf", + aiProcess_ValidateDataStructure); + checkSkinnedScene(sceneImported); + sceneImported = importer.ReadFile( + ASSIMP_TEST_MODELS_DIR "/glTF2/simple_skin/quad_all_out.glb", + aiProcess_ValidateDataStructure); + checkSkinnedScene(sceneImported); + + +} + TEST_F(utglTF2ImportExport, import_cameras) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/cameras/Cameras.gltf", From 01322ec831b5ceccfe1d7dfc10b5806cdb26381e Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 7 Oct 2023 17:49:29 +0200 Subject: [PATCH 2/6] Fix Warning: Use float instead of double --- test/unit/utglTF2ImportExport.cpp | 45 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index 867248734..4c90a7591 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -506,7 +506,7 @@ TEST_F(utglTF2ImportExport, bug_import_simple_skin) { } bool checkSkinnedScene(const aiScene *scene){ - float eps = 0.001; + float eps = 0.001f; bool result = true; EXPECT_EQ(scene->mNumMeshes, 1u); EXPECT_EQ(scene->mMeshes[0]->mNumBones, 10u); @@ -525,16 +525,16 @@ bool checkSkinnedScene(const aiScene *scene){ EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].z - 0), eps); uint numWeights[] = {4u, 4u, 4u, 4u, 2u , 1u, 1u, 2u, 1u, 1u}; - float weights[10][4] = {{0.207, 0.291, 0.057, 0.303}, - {0.113, 0.243, 0.499, 0.251}, - {0.005, 0.010, 0.041, 0.093}, - {0.090, 0.234, 0.404, 0.243}, - {0.090, 0.222, 0.000, 0.000}, - {0.216, 0.000, 0.000, 0.000}, - {0.058, 0.000, 0.000, 0.000}, - {0.086, 0.000, 0.000, 0.111}, - {0.088, 0.000, 0.000, 0.000}, - {0.049, 0.000, 0.000, 0.000}}; + float weights[10][4] = {{0.207f, 0.291f, 0.057f, 0.303f}, + {0.113f, 0.243f, 0.499f, 0.251f}, + {0.005f, 0.010f, 0.041f, 0.093f}, + {0.090f, 0.234f, 0.404f, 0.243f}, + {0.090f, 0.222f, 0.000f, 0.000f}, + {0.216f, 0.000f, 0.000f, 0.000f}, + {0.058f, 0.000f, 0.000f, 0.000f}, + {0.086f, 0.000f, 0.000f, 0.111f}, + {0.088f, 0.000f, 0.000f, 0.000f}, + {0.049f, 0.000f, 0.000f, 0.000f}}; for (size_t boneIndex = 0; boneIndex < 10u; ++boneIndex) { EXPECT_EQ(scene->mMeshes[0]->mBones[boneIndex]->mNumWeights, numWeights[boneIndex]); std::map map; @@ -548,14 +548,13 @@ bool checkSkinnedScene(const aiScene *scene){ auto weight = map[jointIndex]; EXPECT_LT(abs(ai_real(weight) - ai_real(weights[boneIndex][jointIndex])), 0.002); } - } return result; } void checkSkinnedSceneLimited(const aiScene *scene){ - float eps = 0.001; + float eps = 0.001f; EXPECT_EQ(scene->mNumMeshes, 1u); EXPECT_EQ(scene->mMeshes[0]->mNumBones, 10u); EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u); @@ -573,16 +572,16 @@ void checkSkinnedSceneLimited(const aiScene *scene){ EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].z - 0), eps); uint numWeights[] = {4u, 4u, 1u, 4u, 1u , 1u, 1u, 1u, 1u, 1u}; - float weights[10][4] = {{0.207, 0.291, 0.057, 0.303}, - {0.113, 0.243, 0.499, 0.251}, - {0.000, 0.000, 0.041, 0.000}, - {0.090, 0.234, 0.404, 0.243}, - {0.000, 0.222, 0.000, 0.000}, - {0.216, 0.000, 0.000, 0.000}, - {0.000, 0.000, 0.000, 0.000}, - {0.000, 0.000, 0.000, 0.111}, - {0.000, 0.000, 0.000, 0.000}, - {0.000, 0.000, 0.000, 0.000}}; + float weights[10][4] = {{0.207f, 0.291f, 0.057f, 0.303f}, + {0.113f, 0.243f, 0.499f, 0.251f}, + {0.000f, 0.000f, 0.041f, 0.000f}, + {0.090f, 0.234f, 0.404f, 0.243f}, + {0.000f, 0.222f, 0.000f, 0.000f}, + {0.216f, 0.000f, 0.000f, 0.000f}, + {0.000f, 0.000f, 0.000f, 0.000f}, + {0.000f, 0.000f, 0.000f, 0.111f}, + {0.000f, 0.000f, 0.000f, 0.000f}, + {0.000f, 0.000f, 0.000f, 0.000f}}; for (size_t boneIndex = 0; boneIndex < 10u; ++boneIndex) { EXPECT_EQ(scene->mMeshes[0]->mBones[boneIndex]->mNumWeights, numWeights[boneIndex]); std::map map; From 1ee13872b1ebf20a85752261dc41dab2fcd7d09f Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 7 Oct 2023 18:04:25 +0200 Subject: [PATCH 3/6] Update utglTF2ImportExport.cpp --- test/unit/utglTF2ImportExport.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index 4c90a7591..1104b37c9 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -524,7 +524,7 @@ bool checkSkinnedScene(const aiScene *scene){ EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].y - 1), eps); EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].z - 0), eps); - uint numWeights[] = {4u, 4u, 4u, 4u, 2u , 1u, 1u, 2u, 1u, 1u}; + unsigned int numWeights[] = {4u, 4u, 4u, 4u, 2u , 1u, 1u, 2u, 1u, 1u}; float weights[10][4] = {{0.207f, 0.291f, 0.057f, 0.303f}, {0.113f, 0.243f, 0.499f, 0.251f}, {0.005f, 0.010f, 0.041f, 0.093f}, @@ -571,7 +571,7 @@ void checkSkinnedSceneLimited(const aiScene *scene){ EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].y - 1), eps); EXPECT_LT(abs(scene->mMeshes[0]->mVertices[3].z - 0), eps); - uint numWeights[] = {4u, 4u, 1u, 4u, 1u , 1u, 1u, 1u, 1u, 1u}; + unsigned int numWeights[] = {4u, 4u, 1u, 4u, 1u , 1u, 1u, 1u, 1u, 1u}; float weights[10][4] = {{0.207f, 0.291f, 0.057f, 0.303f}, {0.113f, 0.243f, 0.499f, 0.251f}, {0.000f, 0.000f, 0.041f, 0.000f}, From 3c1423d5a5f15c3803ade6ba759e384590a0fad4 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 7 Oct 2023 18:43:05 +0200 Subject: [PATCH 4/6] Replace uint by unsigned int --- test/unit/utglTF2ImportExport.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index 1104b37c9..8b976ce42 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -537,7 +537,7 @@ bool checkSkinnedScene(const aiScene *scene){ {0.049f, 0.000f, 0.000f, 0.000f}}; for (size_t boneIndex = 0; boneIndex < 10u; ++boneIndex) { EXPECT_EQ(scene->mMeshes[0]->mBones[boneIndex]->mNumWeights, numWeights[boneIndex]); - std::map map; + std::map map; for (size_t jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex){ auto key = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mVertexId; auto weight = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mWeight; @@ -584,7 +584,7 @@ void checkSkinnedSceneLimited(const aiScene *scene){ {0.000f, 0.000f, 0.000f, 0.000f}}; for (size_t boneIndex = 0; boneIndex < 10u; ++boneIndex) { EXPECT_EQ(scene->mMeshes[0]->mBones[boneIndex]->mNumWeights, numWeights[boneIndex]); - std::map map; + std::map map; for (size_t jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex){ auto key = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mVertexId; auto weight = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mWeight; From 2f78d48d6bfc415d4f60853148b5f607930fe9a6 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 8 Oct 2023 14:25:11 +0200 Subject: [PATCH 5/6] Fix: Warning implicite convertion --- test/unit/utglTF2ImportExport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index 8b976ce42..535042682 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -544,7 +544,7 @@ bool checkSkinnedScene(const aiScene *scene){ map[key] = weight; } - for (size_t jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex) { + for (unsigned int jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex) { auto weight = map[jointIndex]; EXPECT_LT(abs(ai_real(weight) - ai_real(weights[boneIndex][jointIndex])), 0.002); } From 5d60cf228ad42882a7c4fad02140d4a1a33ae0e9 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 8 Oct 2023 15:20:44 +0200 Subject: [PATCH 6/6] Fix: Waning implicite cast --- test/unit/utglTF2ImportExport.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index 535042682..6778e2679 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -582,15 +582,15 @@ void checkSkinnedSceneLimited(const aiScene *scene){ {0.000f, 0.000f, 0.000f, 0.111f}, {0.000f, 0.000f, 0.000f, 0.000f}, {0.000f, 0.000f, 0.000f, 0.000f}}; - for (size_t boneIndex = 0; boneIndex < 10u; ++boneIndex) { + for (unsigned int boneIndex = 0; boneIndex < 10u; ++boneIndex) { EXPECT_EQ(scene->mMeshes[0]->mBones[boneIndex]->mNumWeights, numWeights[boneIndex]); std::map map; - for (size_t jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex){ + for (unsigned int jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex){ auto key = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mVertexId; auto weight = scene->mMeshes[0]->mBones[boneIndex]->mWeights[jointIndex].mWeight; map[key] = weight; } - for (size_t jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex) { + for (unsigned int jointIndex = 0; jointIndex < scene->mMeshes[0]->mBones[boneIndex]->mNumWeights; ++jointIndex) { auto weight = map[jointIndex]; EXPECT_LT(std::abs(ai_real(weight) - ai_real(weights[boneIndex][jointIndex])), 0.002); }