Skip to content

Commit 08f6f5c

Browse files
committed
#4214 Weights and Joints remap
1 parent 11ece68 commit 08f6f5c

File tree

3 files changed

+90
-4
lines changed

3 files changed

+90
-4
lines changed

indra/llprimitive/llmodel.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,93 @@ void LLModel::remapVolumeFaces()
112112
}
113113
}
114114

115+
void LLModel::remapSkinWeightsAndJoints()
116+
{
117+
if (mSkinWeights.empty())
118+
{
119+
return;
120+
}
121+
122+
mPosition.clear();
123+
124+
// Make a list of positions
125+
std::set<LLVector3> positions;
126+
for (S32 i = 0; i < getNumVolumeFaces(); ++i)
127+
{
128+
for (S32 j = 0; j < mVolumeFaces[i].mNumVertices; ++j)
129+
{
130+
positions.emplace(mVolumeFaces[i].mPositions[j].getF32ptr());
131+
}
132+
}
133+
134+
// Build new list of weights and record used joints
135+
weight_map replacement_weights;
136+
std::vector<S32> joint_index_use_count;
137+
size_t joint_count = mSkinInfo.mJointNames.size();
138+
joint_index_use_count.resize(joint_count, 0);
139+
for (const LLVector3& pos : positions)
140+
{
141+
mPosition.push_back(pos);
142+
auto found = mSkinWeights.find(pos);
143+
if (found != mSkinWeights.end())
144+
{
145+
replacement_weights[pos] = found->second;
146+
147+
for (auto& weight : found->second)
148+
{
149+
if (joint_count > weight.mJointIdx)
150+
{
151+
joint_index_use_count[weight.mJointIdx]++;
152+
}
153+
}
154+
}
155+
}
156+
157+
// go over joint data and remap joints
158+
// prepare joint map
159+
std::vector<std::string> replacement_joint_names;
160+
std::vector<S32> replacement_joint_nums;
161+
LLMeshSkinInfo::matrix_list_t replacement_inv_bind;
162+
LLMeshSkinInfo::matrix_list_t replacement_alt_bind;
163+
std::vector<S32> index_map;
164+
index_map.resize(joint_count);
165+
S32 replacement_index = 0;
166+
167+
for (S32 i = 0; i < joint_count; i++)
168+
{
169+
if (joint_index_use_count[i] > 0)
170+
{
171+
replacement_joint_names.push_back(mSkinInfo.mJointNames[i]);
172+
replacement_joint_nums.push_back(mSkinInfo.mJointNums[i]);
173+
replacement_inv_bind.push_back(mSkinInfo.mInvBindMatrix[i]);
174+
replacement_alt_bind.push_back(mSkinInfo.mAlternateBindMatrix[i]);
175+
index_map[i] = replacement_index++;
176+
}
177+
}
178+
179+
// Apply new data
180+
mSkinInfo.mJointNames.clear();
181+
mSkinInfo.mJointNames = replacement_joint_names;
182+
mSkinInfo.mJointNums.clear();
183+
mSkinInfo.mJointNums = replacement_joint_nums;
184+
mSkinInfo.mInvBindMatrix.clear();
185+
mSkinInfo.mInvBindMatrix = replacement_inv_bind;
186+
mSkinInfo.mAlternateBindMatrix.clear();
187+
mSkinInfo.mAlternateBindMatrix = replacement_alt_bind;
188+
189+
// remap weights
190+
for (auto& weights : replacement_weights)
191+
{
192+
for (auto& weight : weights.second)
193+
{
194+
weight.mJointIdx = index_map[weight.mJointIdx];
195+
}
196+
}
197+
198+
mSkinWeights.clear();
199+
mSkinWeights = replacement_weights;
200+
}
201+
115202
void LLModel::optimizeVolumeFaces()
116203
{
117204
for (S32 i = 0; i < getNumVolumeFaces(); ++i)

indra/llprimitive/llmodel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ class LLModel : public LLVolume
205205
void normalizeVolumeFacesAndWeights();
206206
void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL);
207207
void remapVolumeFaces();
208+
void remapSkinWeightsAndJoints();
208209
void optimizeVolumeFaces();
209210
void offsetMesh( const LLVector3& pivotPoint );
210211
void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out) const;

indra/newview/gltf/llgltfloader.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,6 @@ void LLGLTFLoader::addModelToScene(
165165
{
166166
current_model->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder);
167167

168-
// remove unused/redundant vertices after normalizing
169-
current_model->remapVolumeFaces();
170-
171168
volume_faces = static_cast<U32>(remainder.size());
172169

173170
// Don't add to scene yet because weights and materials aren't ready.
@@ -215,7 +212,8 @@ void LLGLTFLoader::addModelToScene(
215212
{
216213
// remove unused/redundant vertices
217214
current_model->remapVolumeFaces();
218-
// Todo: go over skin weights, joints, matrices and remove unused ones
215+
// remove unused/redundant weights and joints
216+
current_model->remapSkinWeightsAndJoints();
219217

220218
mModelList.push_back(model);
221219

0 commit comments

Comments
 (0)