summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llprimitive/llmodel.cpp87
-rw-r--r--indra/llprimitive/llmodel.h1
-rw-r--r--indra/newview/gltf/llgltfloader.cpp6
3 files changed, 90 insertions, 4 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index c67dac2733..bc9f62b6c0 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -112,6 +112,93 @@ void LLModel::remapVolumeFaces()
}
}
+void LLModel::remapSkinWeightsAndJoints()
+{
+ if (mSkinWeights.empty())
+ {
+ return;
+ }
+
+ mPosition.clear();
+
+ // Make a list of positions
+ std::set<LLVector3> positions;
+ for (S32 i = 0; i < getNumVolumeFaces(); ++i)
+ {
+ for (S32 j = 0; j < mVolumeFaces[i].mNumVertices; ++j)
+ {
+ positions.emplace(mVolumeFaces[i].mPositions[j].getF32ptr());
+ }
+ }
+
+ // Build new list of weights and record used joints
+ weight_map replacement_weights;
+ std::vector<S32> joint_index_use_count;
+ size_t joint_count = mSkinInfo.mJointNames.size();
+ joint_index_use_count.resize(joint_count, 0);
+ for (const LLVector3& pos : positions)
+ {
+ mPosition.push_back(pos);
+ auto found = mSkinWeights.find(pos);
+ if (found != mSkinWeights.end())
+ {
+ replacement_weights[pos] = found->second;
+
+ for (auto& weight : found->second)
+ {
+ if (joint_count > weight.mJointIdx)
+ {
+ joint_index_use_count[weight.mJointIdx]++;
+ }
+ }
+ }
+ }
+
+ // go over joint data and remap joints
+ // prepare joint map
+ std::vector<std::string> replacement_joint_names;
+ std::vector<S32> replacement_joint_nums;
+ LLMeshSkinInfo::matrix_list_t replacement_inv_bind;
+ LLMeshSkinInfo::matrix_list_t replacement_alt_bind;
+ std::vector<S32> index_map;
+ index_map.resize(joint_count);
+ S32 replacement_index = 0;
+
+ for (S32 i = 0; i < joint_count; i++)
+ {
+ if (joint_index_use_count[i] > 0)
+ {
+ replacement_joint_names.push_back(mSkinInfo.mJointNames[i]);
+ replacement_joint_nums.push_back(mSkinInfo.mJointNums[i]);
+ replacement_inv_bind.push_back(mSkinInfo.mInvBindMatrix[i]);
+ replacement_alt_bind.push_back(mSkinInfo.mAlternateBindMatrix[i]);
+ index_map[i] = replacement_index++;
+ }
+ }
+
+ // Apply new data
+ mSkinInfo.mJointNames.clear();
+ mSkinInfo.mJointNames = replacement_joint_names;
+ mSkinInfo.mJointNums.clear();
+ mSkinInfo.mJointNums = replacement_joint_nums;
+ mSkinInfo.mInvBindMatrix.clear();
+ mSkinInfo.mInvBindMatrix = replacement_inv_bind;
+ mSkinInfo.mAlternateBindMatrix.clear();
+ mSkinInfo.mAlternateBindMatrix = replacement_alt_bind;
+
+ // remap weights
+ for (auto& weights : replacement_weights)
+ {
+ for (auto& weight : weights.second)
+ {
+ weight.mJointIdx = index_map[weight.mJointIdx];
+ }
+ }
+
+ mSkinWeights.clear();
+ mSkinWeights = replacement_weights;
+}
+
void LLModel::optimizeVolumeFaces()
{
for (S32 i = 0; i < getNumVolumeFaces(); ++i)
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 5c6d0a55d2..7fa3a00ee2 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -205,6 +205,7 @@ public:
void normalizeVolumeFacesAndWeights();
void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL);
void remapVolumeFaces();
+ void remapSkinWeightsAndJoints();
void optimizeVolumeFaces();
void offsetMesh( const LLVector3& pivotPoint );
void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out) const;
diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp
index e330c1d611..60c6832058 100644
--- a/indra/newview/gltf/llgltfloader.cpp
+++ b/indra/newview/gltf/llgltfloader.cpp
@@ -165,9 +165,6 @@ void LLGLTFLoader::addModelToScene(
{
current_model->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder);
- // remove unused/redundant vertices after normalizing
- current_model->remapVolumeFaces();
-
volume_faces = static_cast<U32>(remainder.size());
// Don't add to scene yet because weights and materials aren't ready.
@@ -215,7 +212,8 @@ void LLGLTFLoader::addModelToScene(
{
// remove unused/redundant vertices
current_model->remapVolumeFaces();
- // Todo: go over skin weights, joints, matrices and remove unused ones
+ // remove unused/redundant weights and joints
+ current_model->remapSkinWeightsAndJoints();
mModelList.push_back(model);