summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2025-05-15 18:28:25 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2025-05-19 20:40:19 +0300
commit875a4180803aa6903bb13263a63e02b38552b742 (patch)
treed46ff70dc636f4385de54bf8929dc15851a577fa
parentfdeef47611e7496ff5d5fb8f37e3b1f5240a8b14 (diff)
#4080 Import GLTF skin data
-rw-r--r--indra/llprimitive/llmodelloader.cpp2
-rw-r--r--indra/newview/gltf/llgltfloader.cpp85
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml1
3 files changed, 82 insertions, 6 deletions
diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp
index 7facd53a72..8f86b90b69 100644
--- a/indra/llprimitive/llmodelloader.cpp
+++ b/indra/llprimitive/llmodelloader.cpp
@@ -150,6 +150,8 @@ void LLModelLoader::run()
{
mWarningsArray.clear();
doLoadModel();
+ // todo: we are inside of a thread, push this into main thread worker,
+ // not into doOnIdleOneTime that laks tread safety
doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this));
}
diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp
index 11c1b05ee5..8d109b610c 100644
--- a/indra/newview/gltf/llgltfloader.cpp
+++ b/indra/newview/gltf/llgltfloader.cpp
@@ -142,7 +142,7 @@ bool LLGLTFLoader::parseMeshes()
// Populate the joints from skins first.
// There's not many skins - and you can pretty easily iterate through the nodes from that.
- for (auto skin : mGLTFAsset.mSkins)
+ for (auto& skin : mGLTFAsset.mSkins)
{
populateJointFromSkin(skin);
}
@@ -164,7 +164,7 @@ bool LLGLTFLoader::parseMeshes()
coord_system_rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f);
// Gather bounds from all meshes
- for (auto node : mGLTFAsset.mNodes)
+ for (auto &node : mGLTFAsset.mNodes)
{
auto meshidx = node.mMesh;
if (meshidx >= 0 && meshidx < mGLTFAsset.mMeshes.size())
@@ -238,7 +238,7 @@ bool LLGLTFLoader::parseMeshes()
}
// Second pass: Process each node with the global scale and offset
- for (auto node : mGLTFAsset.mNodes)
+ for (auto &node : mGLTFAsset.mNodes)
{
LLMatrix4 transformation;
material_map mats;
@@ -281,7 +281,7 @@ bool LLGLTFLoader::parseMeshes()
transformation = mesh_scale;
if (transformation.determinant() < 0)
{ // negative scales are not supported
- LL_INFOS() << "Negative scale detected, unsupported post-normalization transform. domInstance_geometry: "
+ LL_INFOS("GLTF") << "Negative scale detected, unsupported post-normalization transform. domInstance_geometry: "
<< pModel->mLabel << LL_ENDL;
LLSD args;
args["Message"] = "NegativeScaleNormTrans";
@@ -292,6 +292,60 @@ bool LLGLTFLoader::parseMeshes()
mScene[transformation].push_back(LLModelInstance(pModel, pModel->mLabel, transformation, mats));
stretch_extents(pModel, transformation);
mTransform = saved_transform;
+
+ S32 skin_index = node.mSkin;
+ if (skin_index >= 0 && mGLTFAsset.mSkins.size() > skin_index)
+ {
+ LL::GLTF::Skin& gltf_skin = mGLTFAsset.mSkins[skin_index];
+ LLMeshSkinInfo& skin_info = pModel->mSkinInfo;
+
+ size_t jointCnt = gltf_skin.mJoints.size();
+ if (gltf_skin.mInverseBindMatrices >= 0 && jointCnt != gltf_skin.mInverseBindMatricesData.size())
+ {
+ LL_INFOS("GLTF") << "Bind matrices count mismatch joints count" << LL_ENDL;
+ LLSD args;
+ args["Message"] = "InvBindCountMismatch";
+ mWarningsArray.append(args);
+ }
+
+ for (size_t i = 0; i < jointCnt; ++i)
+ {
+ // Process joint name and idnex
+ S32 joint = gltf_skin.mJoints[i];
+ LL::GLTF::Node& jointNode = mGLTFAsset.mNodes[joint];
+ jointNode.makeMatrixValid();
+
+ std::string legal_name(jointNode.mName);
+ if (mJointMap.find(legal_name) != mJointMap.end())
+ {
+ legal_name = mJointMap[legal_name];
+ }
+ skin_info.mJointNames.push_back(legal_name);
+ skin_info.mJointNums.push_back(-1);
+
+ if (i < gltf_skin.mInverseBindMatricesData.size())
+ {
+ // Process bind matrix
+ LL::GLTF::mat4 gltf_mat = gltf_skin.mInverseBindMatricesData[i];
+ LLMatrix4 gltf_transform(glm::value_ptr(gltf_mat));
+ skin_info.mInvBindMatrix.push_back(LLMatrix4a(gltf_transform));
+
+ LL_DEBUGS("GLTF") << "mInvBindMatrix name: " << legal_name << " val: " << gltf_transform << LL_ENDL;
+
+ // Translate based of mJointList
+ gltf_transform.setTranslation(mJointList[legal_name].getTranslation());
+ skin_info.mAlternateBindMatrix.push_back(LLMatrix4a(gltf_transform));
+ }
+ }
+
+ // "Bind Shape Matrix" is supposed to transform the geometry of the skinned mesh
+ // into the coordinate space of the joints.
+ // In GLTF, this matrix is omitted, and it is assumed that this transform is either
+ // premultiplied with the mesh data, or postmultiplied to the inverse bind matrices.
+ LLMatrix4 bind_shape;
+ bind_shape.setIdentity();
+ skin_info.mBindShapeMatrix.loadu(bind_shape);
+ }
}
else
{
@@ -560,10 +614,29 @@ void LLGLTFLoader::populateJointFromSkin(const LL::GLTF::Skin& skin)
for (auto joint : skin.mJoints)
{
auto jointNode = mGLTFAsset.mNodes[joint];
+
+ std::string legal_name(jointNode.mName);
+ if (mJointMap.find(legal_name) != mJointMap.end())
+ {
+ legal_name = mJointMap[legal_name];
+ }
+ else
+ {
+ LL_INFOS("GLTF") << "Rigged to unrecognized joint name : "
+ << legal_name << LL_ENDL;
+ LLSD args;
+ args["Message"] = "UnrecognizedJoint";
+ args["[NAME]"] = legal_name;
+ mWarningsArray.append(args);
+ }
+
jointNode.makeMatrixValid();
- mJointList[jointNode.mName] = LLMatrix4(glm::value_ptr(jointNode.mMatrix));
- mJointsFromNode.push_front(jointNode.mName);
+ LLMatrix4 gltf_transform = LLMatrix4(glm::value_ptr(jointNode.mMatrix));
+ mJointList[legal_name] = gltf_transform;
+ mJointsFromNode.push_front(legal_name);
+
+ LL_DEBUGS("GLTF") << "mJointList name: " << legal_name << " val: " << gltf_transform << LL_ENDL;
}
}
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index 90223fcda8..99c348c236 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -45,6 +45,7 @@
<string name="UnrecognizedJoint">Rigged to unrecognized joint name [NAME]</string>
<string name="UnknownJoints">Skinning disabled due to [COUNT] unknown joints</string>
<string name="ModelLoaded">Model [MODEL_NAME] loaded</string>
+ <string name="InvBindCountMismatch">Bind matrices count mismatch joints count</string>
<string name="IncompleteTC">Texture coordinates data is not complete.</string>
<string name="PositionNaN">Found NaN while loading position data from DAE-Model, invalid model.</string>