Skip to content

Commit 078cc9b

Browse files
committed
#4080 Rigged mesh support #5
1 parent ab13373 commit 078cc9b

File tree

2 files changed

+89
-25
lines changed

2 files changed

+89
-25
lines changed

indra/newview/gltf/llgltfloader.cpp

Lines changed: 86 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -155,19 +155,19 @@ bool LLGLTFLoader::parseMeshes()
155155

156156
mTransform.setIdentity();
157157

158+
for (auto& node : mGLTFAsset.mNodes)
159+
{
160+
// Make node matrix valid for correct transformation
161+
node.makeMatrixValid();
162+
}
163+
158164
// Populate the joints from skins first.
159165
// There's not many skins - and you can pretty easily iterate through the nodes from that.
160166
for (auto& skin : mGLTFAsset.mSkins)
161167
{
162168
populateJointFromSkin(skin);
163169
}
164170

165-
for (auto& node : mGLTFAsset.mNodes)
166-
{
167-
// Make node matrix valid for correct transformation
168-
node.makeMatrixValid();
169-
}
170-
171171
// Track how many times each mesh name has been used
172172
std::map<std::string, S32> mesh_name_counts;
173173

@@ -218,17 +218,21 @@ bool LLGLTFLoader::parseMeshes()
218218
mesh_scale *= transformation;
219219
transformation = mesh_scale;
220220

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+
}
232236

233237
if (transformation.determinant() < 0)
234238
{ // negative scales are not supported
@@ -256,7 +260,7 @@ bool LLGLTFLoader::parseMeshes()
256260
return true;
257261
}
258262

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
260264
{
261265
if (node_index < 0 || node_index >= static_cast<S32>(asset.mNodes.size()))
262266
{
@@ -342,7 +346,6 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
342346
// Process joint name and idnex
343347
S32 joint = gltf_skin.mJoints[i];
344348
LL::GLTF::Node& jointNode = mGLTFAsset.mNodes[joint];
345-
jointNode.makeMatrixValid();
346349

347350
std::string legal_name(jointNode.mName);
348351
if (mJointMap.find(legal_name) == mJointMap.end())
@@ -688,7 +691,6 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
688691
continue;
689692
}
690693
LL::GLTF::Node& jointNode = mGLTFAsset.mNodes[joint];
691-
jointNode.makeMatrixValid();
692694

693695
std::string legal_name(jointNode.mName);
694696
if (mJointMap.find(legal_name) != mJointMap.end())
@@ -723,8 +725,15 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
723725
// Get the original joint node and use its matrix directly
724726
S32 joint = gltf_skin.mJoints[i];
725727
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));
728737

729738
LL_INFOS("GLTF_DEBUG") << "mAlternateBindMatrix name: " << legal_name << " val: " << original_joint_transform << LL_ENDL;
730739
skin_info.mAlternateBindMatrix.push_back(LLMatrix4a(original_joint_transform));
@@ -771,8 +780,6 @@ void LLGLTFLoader::populateJointFromSkin(const LL::GLTF::Skin& skin)
771780
continue;
772781
}
773782

774-
jointNode.makeMatrixValid();
775-
776783
// Debug: Log original joint matrix
777784
glm::mat4 gltf_joint_matrix = jointNode.mMatrix;
778785
LL_INFOS("GLTF_DEBUG") << "Joint '" << legal_name << "' original matrix:" << LL_ENDL;
@@ -801,6 +808,61 @@ void LLGLTFLoader::populateJointFromSkin(const LL::GLTF::Skin& skin)
801808
}
802809
}
803810

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+
804866
bool LLGLTFLoader::parseMaterials()
805867
{
806868
if (!mGltfLoaded) return false;

indra/newview/gltf/llgltfloader.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,11 @@ class LLGLTFLoader : public LLModelLoader
167167
void uploadMeshes();
168168
bool parseMaterials();
169169
void uploadMaterials();
170-
void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform);
170+
void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) const;
171171
bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats, S32 instance_count);
172172
void populateJointFromSkin(const LL::GLTF::Skin& skin);
173+
S32 findValidRootJoint(S32 source_joint, const LL::GLTF::Skin& gltf_skin) const;
174+
S32 findGLTFRootJoint(const LL::GLTF::Skin& gltf_skin) const; // if there are multiple roots, gltf stores them under one commor joint
173175
LLUUID imageBufferToTextureUUID(const gltf_texture& tex);
174176

175177
// bool mPreprocessGLTF;

0 commit comments

Comments
 (0)