diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2025-05-15 18:28:25 +0300 | 
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2025-05-19 20:40:19 +0300 | 
| commit | 875a4180803aa6903bb13263a63e02b38552b742 (patch) | |
| tree | d46ff70dc636f4385de54bf8929dc15851a577fa /indra | |
| parent | fdeef47611e7496ff5d5fb8f37e3b1f5240a8b14 (diff) | |
#4080 Import GLTF skin data
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llprimitive/llmodelloader.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/gltf/llgltfloader.cpp | 85 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_model_preview.xml | 1 | 
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> | 
