@@ -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+
115202void LLModel::optimizeVolumeFaces ()
116203{
117204 for (S32 i = 0 ; i < getNumVolumeFaces (); ++i)
0 commit comments