@@ -175,6 +175,16 @@ void LLGLTFLoader::addModelToScene(
175175 U32 face_limit = (submodel_limit + 1 ) * LL_SCULPT_MESH_MAX_FACES;
176176 if (face_limit < volume_faces)
177177 {
178+ LL_WARNS (" GLTF_IMPORT" ) << " Model contains " << volume_faces
179+ << " faces, exceeding the limit of " << face_limit << LL_ENDL;
180+
181+ LLSD args;
182+ args[" Message" ] = " ModelTooManySubmodels" ;
183+ args[" MODEL_NAME" ] = pModel->mLabel ;
184+ args[" SUBMODEL_COUNT" ] = static_cast <S32>(llfloor ((F32)volume_faces / LL_SCULPT_MESH_MAX_FACES));
185+ args[" SUBMODEL_LIMIT" ] = static_cast <S32>(submodel_limit);
186+ mWarningsArray .append (args);
187+
178188 pModel->setNumVolumeFaces (face_limit);
179189 }
180190
@@ -284,7 +294,9 @@ bool LLGLTFLoader::parseMeshes()
284294
285295 // Track how many times each mesh name has been used
286296 std::map<std::string, S32> mesh_name_counts;
287- U32 submodel_limit = mGLTFAsset .mNodes .size () > 0 ? mGeneratedModelLimit / (U32)mGLTFAsset .mNodes .size () : 0 ;
297+
298+ // For now use mesh count, but might be better to do 'mNodes.size() - joints count'.
299+ U32 submodel_limit = mGLTFAsset .mMeshes .size () > 0 ? mGeneratedModelLimit / (U32)mGLTFAsset .mMeshes .size () : 0 ;
288300
289301 // Check if we have scenes defined
290302 if (!mGLTFAsset .mScenes .empty ())
@@ -318,20 +330,7 @@ bool LLGLTFLoader::parseMeshes()
318330 return false ;
319331 }
320332
321- // Check total model count against limit
322- U32 total_models = static_cast <U32>(mModelList .size ());
323- if (total_models > mGeneratedModelLimit )
324- {
325- LL_WARNS (" GLTF_IMPORT" ) << " Model contains " << total_models
326- << " mesh parts, exceeding the limit of " << mGeneratedModelLimit << LL_ENDL;
327-
328- LLSD args;
329- args[" Message" ] = " TooManyMeshParts" ;
330- args[" PART_COUNT" ] = static_cast <S32>(total_models);
331- args[" LIMIT" ] = static_cast <S32>(mGeneratedModelLimit );
332- mWarningsArray .append (args);
333- return false ;
334- }
333+ checkGlobalJointUsage ();
335334
336335 return true ;
337336}
@@ -478,7 +477,7 @@ void LLGLTFLoader::computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S3
478477 }
479478}
480479
481- bool LLGLTFLoader::addJointToModelSkin (LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx) const
480+ bool LLGLTFLoader::addJointToModelSkin (LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx)
482481{
483482 const std::string& legal_name = mJointNames [gltf_skin_idx][gltf_joint_idx];
484483 if (legal_name.empty ())
@@ -493,6 +492,9 @@ bool LLGLTFLoader::addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_
493492 skin_info.mInvBindMatrix .push_back (mInverseBindMatrices [gltf_skin_idx][gltf_joint_idx]);
494493 skin_info.mAlternateBindMatrix .push_back (mAlternateBindMatrices [gltf_skin_idx][gltf_joint_idx]);
495494
495+ // Track joint usage for this skin, for the sake of unused joints detection
496+ mJointUsage [gltf_skin_idx][gltf_joint_idx]++;
497+
496498 return true ;
497499}
498500
@@ -885,6 +887,7 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
885887 std::vector<U16> indices_16;
886888 std::vector<S64> vertices_remap; // should it be a point map?
887889 vertices_remap.resize (faceVertices.size (), -1 );
890+ S32 created_faces = 0 ;
888891 std::vector<LLVolumeFace::VertexData> face_verts;
889892 min = glm::vec3 (FLT_MAX);
890893 max = glm::vec3 (-FLT_MAX);
@@ -933,6 +936,7 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
933936 face.mExtents [1 ] = LLVector4a (max.x , max.y , max.z , 0 );
934937 pModel->getVolumeFaces ().push_back (face);
935938 pModel->getMaterialList ().push_back (materialName);
939+ created_faces++;
936940
937941 std::fill (vertices_remap.begin (), vertices_remap.end (), -1 );
938942 indices_16.clear ();
@@ -950,7 +954,17 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
950954 face.mExtents [1 ] = LLVector4a (max.x , max.y , max.z , 0 );
951955 pModel->getVolumeFaces ().push_back (face);
952956 pModel->getMaterialList ().push_back (materialName);
957+ created_faces++;
953958 }
959+
960+ LL_INFOS (" GLTF_IMPORT" ) << " Primitive " << pModel->mLabel
961+ << " is over vertices limit, it was split into " << created_faces
962+ << " faces" << LL_ENDL;
963+ LLSD args;
964+ args[" Message" ] = " ModelSplitPrimitive" ;
965+ args[" MODEL_NAME" ] = pModel->mLabel ;
966+ args[" FACE_COUNT" ] = created_faces;
967+ mWarningsArray .append (args);
954968 }
955969 else
956970 {
@@ -1094,7 +1108,7 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
10941108 << " Count: " << (S32)skin_info.mInvBindMatrix .size ()
10951109 << " Limit:" << (S32)LL_MAX_JOINTS_PER_MESH_OBJECT << LL_ENDL;
10961110 LLSD args;
1097- args[" Message" ] = " ModelTooManyJoint " ;
1111+ args[" Message" ] = " ModelTooManyJoints " ;
10981112 args[" MODEL_NAME" ] = pModel->mLabel ;
10991113 args[" JOINT_COUNT" ] = (S32)skin_info.mInvBindMatrix .size ();
11001114 args[" MAX" ] = (S32)LL_MAX_JOINTS_PER_MESH_OBJECT;
@@ -1135,6 +1149,7 @@ void LLGLTFLoader::populateJointsFromSkin(S32 skin_idx)
11351149 mInverseBindMatrices .resize (skin_idx + 1 );
11361150 mAlternateBindMatrices .resize (skin_idx + 1 );
11371151 mJointNames .resize (skin_idx + 1 );
1152+ mJointUsage .resize (skin_idx + 1 );
11381153 mValidJointsCount .resize (skin_idx + 1 , 0 );
11391154 }
11401155
@@ -1173,20 +1188,6 @@ void LLGLTFLoader::populateJointsFromSkin(S32 skin_idx)
11731188 }
11741189 }
11751190
1176- if (mValidJointsCount [skin_idx] > LL_MAX_JOINTS_PER_MESH_OBJECT)
1177- {
1178- LL_WARNS (" GLTF_IMPORT" ) << " Too many jonts, will strip unused joints"
1179- << " Count: " << mValidJointsCount [skin_idx]
1180- << " Limit:" << (S32)LL_MAX_JOINTS_PER_MESH_OBJECT << LL_ENDL;
1181-
1182- LLSD args;
1183- args[" Message" ] = " SkinJointsOverLimit" ;
1184- args[" SKIN_INDEX" ] = (S32)skin_idx;
1185- args[" JOINT_COUNT" ] = mValidJointsCount [skin_idx];
1186- args[" MAX" ] = (S32)LL_MAX_JOINTS_PER_MESH_OBJECT;
1187- mWarningsArray .append (args);
1188- }
1189-
11901191 // Go over viewer joints and build overrides
11911192 glm::mat4 ident (1.0 );
11921193 for (auto &viewer_data : mViewerJointData )
@@ -1210,6 +1211,7 @@ void LLGLTFLoader::populateJointsFromSkin(S32 skin_idx)
12101211 {
12111212 mJointNames [skin_idx].emplace_back ();
12121213 }
1214+ mJointUsage [skin_idx].push_back (0 );
12131215
12141216 // Compute bind matrices
12151217
@@ -1268,6 +1270,21 @@ void LLGLTFLoader::populateJointsFromSkin(S32 skin_idx)
12681270 mJointsFromNode .push_front (legal_name);
12691271 }
12701272 }
1273+
1274+ S32 valid_joints = mValidJointsCount [skin_idx];
1275+ if (valid_joints < joint_count)
1276+ {
1277+ LL_WARNS (" GLTF_IMPORT" ) << " Skin " << skin_idx
1278+ << " defines " << joint_count
1279+ << " joints, but only " << valid_joints
1280+ << " were recognized and are compatible." << LL_ENDL;
1281+ LLSD args;
1282+ args[" Message" ] = " SkinUsupportedJoints" ;
1283+ args[" SKIN_INDEX" ] = skin_idx;
1284+ args[" JOINT_COUNT" ] = joint_count;
1285+ args[" LEGAL_COUNT" ] = valid_joints;
1286+ mWarningsArray .append (args);
1287+ }
12711288}
12721289
12731290void LLGLTFLoader::populateJointGroups ()
@@ -1279,109 +1296,6 @@ void LLGLTFLoader::populateJointGroups()
12791296 }
12801297}
12811298
1282-
1283- S32 LLGLTFLoader::findClosestValidJoint (S32 source_joint, const LL::GLTF::Skin& gltf_skin) const
1284- {
1285- S32 source_joint_node = gltf_skin.mJoints [source_joint];
1286- S32 root_node = source_joint_node;
1287- S32 found_node = source_joint_node;
1288- S32 size = (S32)gltf_skin.mJoints .size ();
1289- do
1290- {
1291- root_node = found_node;
1292- for (S32 i = 0 ; i < size; i++)
1293- {
1294- S32 joint = gltf_skin.mJoints [i];
1295- const LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [joint];
1296- std::vector<S32>::const_iterator it = std::find (jointNode.mChildren .begin (), jointNode.mChildren .end (), root_node);
1297- if (it != jointNode.mChildren .end ())
1298- {
1299- // Found node's parent
1300- found_node = joint;
1301- if (mJointMap .find (jointNode.mName ) != mJointMap .end ())
1302- {
1303- return i;
1304- }
1305- break ;
1306- }
1307- }
1308- } while (root_node != found_node);
1309-
1310- return -1 ;
1311- }
1312-
1313- S32 LLGLTFLoader::findValidRootJointNode (S32 source_joint_node, const LL::GLTF::Skin& gltf_skin) const
1314- {
1315- S32 root_node = 0 ;
1316- S32 found_node = source_joint_node;
1317- S32 size = (S32)gltf_skin.mJoints .size ();
1318- do
1319- {
1320- root_node = found_node;
1321- for (S32 i = 0 ; i < size; i++)
1322- {
1323- S32 joint = gltf_skin.mJoints [i];
1324- const LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [joint];
1325-
1326- if (mJointMap .find (jointNode.mName ) != mJointMap .end ())
1327- {
1328- std::vector<S32>::const_iterator it = std::find (jointNode.mChildren .begin (), jointNode.mChildren .end (), root_node);
1329- if (it != jointNode.mChildren .end ())
1330- {
1331- // Found node's parent
1332- found_node = joint;
1333- break ;
1334- }
1335- }
1336- }
1337- } while (root_node != found_node);
1338-
1339- return root_node;
1340- }
1341-
1342- S32 LLGLTFLoader::findGLTFRootJointNode (const LL::GLTF::Skin& gltf_skin) const
1343- {
1344- S32 root_node = 0 ;
1345- S32 found_node = 0 ;
1346- S32 size = (S32)gltf_skin.mJoints .size ();
1347- do
1348- {
1349- root_node = found_node;
1350- for (S32 i = 0 ; i < size; i++)
1351- {
1352- S32 joint = gltf_skin.mJoints [i];
1353- const LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [joint];
1354- std::vector<S32>::const_iterator it = std::find (jointNode.mChildren .begin (), jointNode.mChildren .end (), root_node);
1355- if (it != jointNode.mChildren .end ())
1356- {
1357- // Found node's parent
1358- found_node = joint;
1359- break ;
1360- }
1361- }
1362- } while (root_node != found_node);
1363-
1364- LL_INFOS (" GLTF_DEBUG" ) << " mJointList name: " ;
1365- const LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [root_node];
1366- LL_CONT << jointNode.mName << " index: " << root_node << LL_ENDL;
1367- return root_node;
1368- }
1369-
1370- S32 LLGLTFLoader::findParentNode (S32 node) const
1371- {
1372- S32 size = (S32)mGLTFAsset .mNodes .size ();
1373- for (S32 i = 0 ; i < size; i++)
1374- {
1375- const LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [i];
1376- std::vector<S32>::const_iterator it = std::find (jointNode.mChildren .begin (), jointNode.mChildren .end (), node);
1377- if (it != jointNode.mChildren .end ())
1378- {
1379- return i;
1380- }
1381- }
1382- return -1 ;
1383- }
1384-
13851299void LLGLTFLoader::buildJointGroup (LLJointData& viewer_data, const std::string &parent_group)
13861300{
13871301 JointGroups& jount_group_data = mJointGroups [viewer_data.mName ];
@@ -1436,11 +1350,22 @@ void LLGLTFLoader::buildOverrideMatrix(LLJointData& viewer_data, joints_data_map
14361350
14371351 node.mOverrideMatrix = glm::recompose (glm::vec3 (1 , 1 , 1 ), glm::identity<glm::quat>(), translation_override, glm::vec3 (0 , 0 , 0 ), glm::vec4 (0 , 0 , 0 , 1 ));
14381352
1439- glm::mat4 override_joint = node.mOverrideMatrix ;
1440- override_joint = glm::scale (override_joint, viewer_data.mScale );
1353+ glm::mat4 overriden_joint = node.mOverrideMatrix ;
1354+ // This is incomplete or even wrong.
1355+ // Viewer allows overrides, which are base joint with applied translation override.
1356+ // So we should be taking viewer joint matrix and replacing translation part with an override.
1357+ // Or should rebuild the matrix from viewer_data.scale, viewer_data.rotation, translation_override parts.
1358+ overriden_joint = glm::scale (overriden_joint, viewer_data.mScale );
14411359
1442- rest = parent_rest * override_joint;
1443- node.mOverrideRestMatrix = rest;
1360+ rest = parent_rest * overriden_joint;
1361+ if (viewer_data.mIsJoint )
1362+ {
1363+ node.mOverrideRestMatrix = rest;
1364+ }
1365+ else
1366+ {
1367+ node.mOverrideRestMatrix = parent_support_rest * overriden_joint;
1368+ }
14441369 }
14451370 else
14461371 {
@@ -1604,6 +1529,47 @@ void LLGLTFLoader::checkForXYrotation(const LL::GLTF::Skin& gltf_skin)
16041529 }
16051530}
16061531
1532+ void LLGLTFLoader::checkGlobalJointUsage ()
1533+ {
1534+ // Check if some joints remained unused
1535+ for (S32 skin_idx = 0 ; skin_idx < (S32)mGLTFAsset .mSkins .size (); ++skin_idx)
1536+ {
1537+ const LL::GLTF::Skin& gltf_skin = mGLTFAsset .mSkins [skin_idx];
1538+ S32 joint_count = (S32)gltf_skin.mJoints .size ();
1539+ S32 used_joints = 0 ;
1540+ for (S32 i = 0 ; i < joint_count; ++i)
1541+ {
1542+ S32 joint = gltf_skin.mJoints [i];
1543+ if (mJointUsage [skin_idx][i] == 0 )
1544+ {
1545+ // Joint is unused, log it
1546+ LL_INFOS (" GLTF_DEBUG" ) << " Joint " << mJointNames [skin_idx][i]
1547+ << " in skin " << skin_idx << " is unused." << LL_ENDL;
1548+ }
1549+ else
1550+ {
1551+ used_joints++;
1552+ }
1553+ }
1554+
1555+ S32 valid_joints = mValidJointsCount [skin_idx];
1556+ if (valid_joints > used_joints)
1557+ {
1558+ S32 unsed_joints = valid_joints - used_joints;
1559+ LL_INFOS (" GLTF_IMPORT" ) << " Skin " << skin_idx
1560+ << " declares " << valid_joints
1561+ << " valid joints, of them " << unsed_joints
1562+ << " remained unused" << LL_ENDL;
1563+ LLSD args;
1564+ args[" Message" ] = " SkinUnusedJoints" ;
1565+ args[" SKIN_INDEX" ] = (S32)skin_idx;
1566+ args[" JOINT_COUNT" ] = valid_joints;
1567+ args[" USED_COUNT" ] = used_joints;
1568+ mWarningsArray .append (args);
1569+ }
1570+ }
1571+ }
1572+
16071573std::string LLGLTFLoader::extractTextureToTempFile (S32 textureIndex, const std::string& texture_type)
16081574{
16091575 if (textureIndex < 0 || textureIndex >= mGLTFAsset .mTextures .size ())
0 commit comments