Skip to content

Commit dd8d741

Browse files
committed
#4242 Better issue logging
1 parent 64b56d7 commit dd8d741

File tree

4 files changed

+113
-146
lines changed

4 files changed

+113
-146
lines changed

indra/newview/app_settings/settings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<key>ImporterModelLimit</key>
2828
<map>
2929
<key>Comment</key>
30-
<string>Limits amount of importer generated models for dae files</string>
30+
<string>Limits amount of importer generated (when over 8 faces) models for dae and gltf files</string>
3131
<key>Persist</key>
3232
<integer>1</integer>
3333
<key>Type</key>

indra/newview/gltf/llgltfloader.cpp

Lines changed: 104 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -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

12731290
void 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-
13851299
void 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+
16071573
std::string LLGLTFLoader::extractTextureToTempFile(S32 textureIndex, const std::string& texture_type)
16081574
{
16091575
if (textureIndex < 0 || textureIndex >= mGLTFAsset.mTextures.size())

indra/newview/gltf/llgltfloader.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class LLGLTFLoader : public LLModelLoader
116116
bind_matrices_t mInverseBindMatrices;
117117
bind_matrices_t mAlternateBindMatrices;
118118
joint_names_t mJointNames; // empty string when no legal name for a given idx
119+
std::vector<std::vector<S32>> mJointUsage; // detect and warn about unsed joints
119120

120121
// what group a joint belongs to.
121122
// For purpose of stripping unused groups when joints are over limit.
@@ -134,22 +135,19 @@ class LLGLTFLoader : public LLModelLoader
134135
bool parseMeshes();
135136
void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) const;
136137
void processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params);
137-
bool addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx) const;
138+
bool addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx);
138139
bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats, S32 instance_count);
139140
void populateJointsFromSkin(S32 skin_idx);
140141
void populateJointGroups();
141142
void addModelToScene(LLModel* pModel, U32 submodel_limit, const LLMatrix4& transformation, const LLVolumeParams& volume_params, const material_map& mats);
142-
S32 findClosestValidJoint(S32 source_joint, const LL::GLTF::Skin& gltf_skin) const;
143-
S32 findValidRootJointNode(S32 source_joint_node, const LL::GLTF::Skin& gltf_skin) const;
144-
S32 findGLTFRootJointNode(const LL::GLTF::Skin& gltf_skin) const; // if there are multiple roots, gltf stores them under one commor joint
145-
S32 findParentNode(S32 node) const;
146143
void buildJointGroup(LLJointData& viewer_data, const std::string& parent_group);
147144
void buildOverrideMatrix(LLJointData& data, joints_data_map_t &gltf_nodes, joints_name_to_node_map_t &names_to_nodes, glm::mat4& parent_rest, glm::mat4& support_rest) const;
148145
glm::mat4 buildGltfRestMatrix(S32 joint_node_index, const LL::GLTF::Skin& gltf_skin) const;
149146
glm::mat4 buildGltfRestMatrix(S32 joint_node_index, const joints_data_map_t& joint_data) const;
150147
glm::mat4 computeGltfToViewerSkeletonTransform(const joints_data_map_t& joints_data_map, S32 gltf_node_index, const std::string& joint_name) const;
151148
bool checkForXYrotation(const LL::GLTF::Skin& gltf_skin, S32 joint_idx, S32 bind_indx);
152149
void checkForXYrotation(const LL::GLTF::Skin& gltf_skin);
150+
void checkGlobalJointUsage();
153151

154152
std::string extractTextureToTempFile(S32 textureIndex, const std::string& texture_type);
155153

0 commit comments

Comments
 (0)