@@ -155,19 +155,19 @@ bool LLGLTFLoader::parseMeshes()
155
155
156
156
mTransform .setIdentity ();
157
157
158
+ for (auto & node : mGLTFAsset .mNodes )
159
+ {
160
+ // Make node matrix valid for correct transformation
161
+ node.makeMatrixValid ();
162
+ }
163
+
158
164
// Populate the joints from skins first.
159
165
// There's not many skins - and you can pretty easily iterate through the nodes from that.
160
166
for (auto & skin : mGLTFAsset .mSkins )
161
167
{
162
168
populateJointFromSkin (skin);
163
169
}
164
170
165
- for (auto & node : mGLTFAsset .mNodes )
166
- {
167
- // Make node matrix valid for correct transformation
168
- node.makeMatrixValid ();
169
- }
170
-
171
171
// Track how many times each mesh name has been used
172
172
std::map<std::string, S32> mesh_name_counts;
173
173
@@ -218,17 +218,21 @@ bool LLGLTFLoader::parseMeshes()
218
218
mesh_scale *= transformation;
219
219
transformation = mesh_scale;
220
220
221
- // "Bind Shape Matrix" is supposed to transform the geometry of the skinned mesh
222
- // into the coordinate space of the joints.
223
- // In GLTF, this matrix is omitted, and it is assumed that this transform is either
224
- // premultiplied with the mesh data, or postmultiplied to the inverse bind matrices.
225
- //
226
- // TODO: This appers to be missing rotation when joints rotate the model
227
- // or inverted bind matrices are missing inherited rotation
228
- // (based of values the 'bento shoes' mesh might be missing 90 degrees horizontaly
229
- // prior to skinning)
230
- pModel->mSkinInfo .mBindShapeMatrix .loadu (mesh_scale);
231
- LL_INFOS (" GLTF_DEBUG" ) << " Model: " << pModel->mLabel << " mBindShapeMatrix: " << pModel->mSkinInfo .mBindShapeMatrix << LL_ENDL;
221
+ if (node.mSkin >= 0 )
222
+ {
223
+ // "Bind Shape Matrix" is supposed to transform the geometry of the skinned mesh
224
+ // into the coordinate space of the joints.
225
+ // In GLTF, this matrix is omitted, and it is assumed that this transform is either
226
+ // premultiplied with the mesh data, or postmultiplied to the inverse bind matrices.
227
+ //
228
+ // TODO: There appears to be missing rotation when joints rotate the model
229
+ // or inverted bind matrices are missing inherited rotation
230
+ // (based of values the 'bento shoes' mesh might be missing 90 degrees horizontaly
231
+ // prior to skinning)
232
+
233
+ pModel->mSkinInfo .mBindShapeMatrix .loadu (mesh_scale);
234
+ LL_INFOS (" GLTF_DEBUG" ) << " Model: " << pModel->mLabel << " mBindShapeMatrix: " << pModel->mSkinInfo .mBindShapeMatrix << LL_ENDL;
235
+ }
232
236
233
237
if (transformation.determinant () < 0 )
234
238
{ // negative scales are not supported
@@ -256,7 +260,7 @@ bool LLGLTFLoader::parseMeshes()
256
260
return true ;
257
261
}
258
262
259
- void LLGLTFLoader::computeCombinedNodeTransform (const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform)
263
+ void LLGLTFLoader::computeCombinedNodeTransform (const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) const
260
264
{
261
265
if (node_index < 0 || node_index >= static_cast <S32>(asset.mNodes .size ()))
262
266
{
@@ -342,7 +346,6 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
342
346
// Process joint name and idnex
343
347
S32 joint = gltf_skin.mJoints [i];
344
348
LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [joint];
345
- jointNode.makeMatrixValid ();
346
349
347
350
std::string legal_name (jointNode.mName );
348
351
if (mJointMap .find (legal_name) == mJointMap .end ())
@@ -688,7 +691,6 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
688
691
continue ;
689
692
}
690
693
LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [joint];
691
- jointNode.makeMatrixValid ();
692
694
693
695
std::string legal_name (jointNode.mName );
694
696
if (mJointMap .find (legal_name) != mJointMap .end ())
@@ -723,8 +725,15 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
723
725
// Get the original joint node and use its matrix directly
724
726
S32 joint = gltf_skin.mJoints [i];
725
727
LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [joint];
726
- jointNode.makeMatrixValid ();
727
- LLMatrix4 original_joint_transform (glm::value_ptr (jointNode.mMatrix ));
728
+ glm::mat4 joint_mat = jointNode.mMatrix ;
729
+ S32 root_joint = findValidRootJoint (joint, gltf_skin); // skeleton can have multiple real roots
730
+ if (root_joint == joint)
731
+ {
732
+ // This is very likely incomplete in some way.
733
+ // Root shouldn't be the only one to need full coordinate fix
734
+ joint_mat = coord_system_rotation * joint_mat;
735
+ }
736
+ LLMatrix4 original_joint_transform (glm::value_ptr (joint_mat));
728
737
729
738
LL_INFOS (" GLTF_DEBUG" ) << " mAlternateBindMatrix name: " << legal_name << " val: " << original_joint_transform << LL_ENDL;
730
739
skin_info.mAlternateBindMatrix .push_back (LLMatrix4a (original_joint_transform));
@@ -771,8 +780,6 @@ void LLGLTFLoader::populateJointFromSkin(const LL::GLTF::Skin& skin)
771
780
continue ;
772
781
}
773
782
774
- jointNode.makeMatrixValid ();
775
-
776
783
// Debug: Log original joint matrix
777
784
glm::mat4 gltf_joint_matrix = jointNode.mMatrix ;
778
785
LL_INFOS (" GLTF_DEBUG" ) << " Joint '" << legal_name << " ' original matrix:" << LL_ENDL;
@@ -801,6 +808,61 @@ void LLGLTFLoader::populateJointFromSkin(const LL::GLTF::Skin& skin)
801
808
}
802
809
}
803
810
811
+ S32 LLGLTFLoader::findValidRootJoint (S32 source_joint, const LL::GLTF::Skin& gltf_skin) const
812
+ {
813
+ S32 root_joint = 0 ;
814
+ S32 found_joint = source_joint;
815
+ S32 size = (S32)gltf_skin.mJoints .size ();
816
+ do
817
+ {
818
+ root_joint = found_joint;
819
+ for (S32 i = 0 ; i < size; i++)
820
+ {
821
+ S32 joint = gltf_skin.mJoints [i];
822
+ const LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [joint];
823
+
824
+ if (mJointMap .find (jointNode.mName ) != mJointMap .end ())
825
+ {
826
+ std::vector<S32>::const_iterator it = std::find (jointNode.mChildren .begin (), jointNode.mChildren .end (), root_joint);
827
+ if (it != jointNode.mChildren .end ())
828
+ {
829
+ found_joint = joint;
830
+ break ;
831
+ }
832
+ }
833
+ }
834
+ } while (root_joint != found_joint);
835
+
836
+ return root_joint;
837
+ }
838
+
839
+ S32 LLGLTFLoader::findGLTFRootJoint (const LL::GLTF::Skin& gltf_skin) const
840
+ {
841
+ S32 root_joint = 0 ;
842
+ S32 found_joint = 0 ;
843
+ S32 size = (S32)gltf_skin.mJoints .size ();
844
+ do
845
+ {
846
+ root_joint = found_joint;
847
+ for (S32 i = 0 ; i < size; i++)
848
+ {
849
+ S32 joint = gltf_skin.mJoints [i];
850
+ const LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [joint];
851
+ std::vector<S32>::const_iterator it = std::find (jointNode.mChildren .begin (), jointNode.mChildren .end (), root_joint);
852
+ if (it != jointNode.mChildren .end ())
853
+ {
854
+ found_joint = joint;
855
+ break ;
856
+ }
857
+ }
858
+ } while (root_joint != found_joint);
859
+
860
+ LL_INFOS (" GLTF_DEBUG" ) << " mJointList name: " ;
861
+ const LL::GLTF::Node& jointNode = mGLTFAsset .mNodes [root_joint];
862
+ LL_CONT << jointNode.mName << " index: " << root_joint << LL_ENDL;
863
+ return root_joint;
864
+ }
865
+
804
866
bool LLGLTFLoader::parseMaterials ()
805
867
{
806
868
if (!mGltfLoaded ) return false ;
0 commit comments