diff options
| author | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2025-05-14 10:33:01 -0400 | 
|---|---|---|
| committer | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2025-05-14 10:33:01 -0400 | 
| commit | 2efe514f14a0f0b405599301a14413edfce873ee (patch) | |
| tree | 1385b8a967569e154a3b15a3036e046761ce2e1a /indra | |
| parent | d679e7f3bacd7bba5493257f0e6c1c2366bf960a (diff) | |
Make pulling weights per vertex.
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/gltf/llgltfloader.cpp | 88 | ||||
| -rw-r--r-- | indra/newview/gltf/llgltfloader.h | 2 | 
2 files changed, 58 insertions, 32 deletions
| diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp index 7f3f158fd7..2db803ef3e 100644 --- a/indra/newview/gltf/llgltfloader.cpp +++ b/indra/newview/gltf/llgltfloader.cpp @@ -271,6 +271,32 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&                  vert.position = glm::vec3(prim.mPositions[i][0], prim.mPositions[i][1], prim.mPositions[i][2]);                  vert.normal   = glm::vec3(prim.mNormals[i][0], prim.mNormals[i][1], prim.mNormals[i][2]);                  vert.uv0      = glm::vec2(prim.mTexCoords0[i][0],-prim.mTexCoords0[i][1]); + +                if (skinIdx >= 0) +                { +                    auto accessorIdx = prim.mAttributes["JOINTS_0"]; +                    LL::GLTF::Accessor::ComponentType componentType = LL::GLTF::Accessor::ComponentType::UNSIGNED_BYTE; +                    if (accessorIdx >= 0) +                    { +                        auto accessor   = mGLTFAsset.mAccessors[accessorIdx]; +                        componentType = accessor.mComponentType; +                    } + +                    // The GLTF spec allows for either an unsigned byte for joint indices, or an unsigned short. +                    // Detect and unpack accordingly. +                    if (componentType == LL::GLTF::Accessor::ComponentType::UNSIGNED_BYTE) +                    { +                        auto ujoint = glm::unpackUint4x8((U32)(prim.mJoints[i] & 0xFFFFFFFF)); +                        vert.joints = glm::u16vec4(ujoint.x, ujoint.y, ujoint.z, ujoint.w); +                    } +                    else if (componentType == LL::GLTF::Accessor::ComponentType::UNSIGNED_SHORT) +                    { +                        vert.joints = glm::unpackUint4x16(prim.mJoints[i]); +                    } + +                    vert.weights = glm::vec4(prim.mWeights[i]); +                } +                  vertices.push_back(vert);              } @@ -282,6 +308,7 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&              std::vector<LLVolumeFace::VertexData> faceVertices;              glm::vec3 min = glm::vec3(0);              glm::vec3 max = glm::vec3(0); +              for (U32 i = 0; i < vertices.size(); i++)              {                  LLVolumeFace::VertexData vert; @@ -307,45 +334,42 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&                  vert.setNormal(normal);                  vert.mTexCoord = LLVector2(vertices[i].uv0.x, vertices[i].uv0.y);                  faceVertices.push_back(vert); -            } -            if (skinIdx >= 0) -            { -                auto skin = mGLTFAsset.mSkins[skinIdx]; +                 +                // create list of weights that influence this vertex +                LLModel::weight_list weight_list; -                for (int i = 0; i < prim.mJoints.size(); i++) -                { -                    auto accessorIdx = prim.mAttributes["JOINTS_0"]; -                    LL::GLTF::Accessor::ComponentType componentType = LL::GLTF::Accessor::ComponentType::UNSIGNED_BYTE; -                    if (accessorIdx >= 0) -                    { -                        auto accessor   = mGLTFAsset.mAccessors[accessorIdx]; -                        componentType = accessor.mComponentType; -                    } -                    glm::u16vec4 joint; -                    if (componentType == LL::GLTF::Accessor::ComponentType::UNSIGNED_BYTE) +                weight_list.push_back(LLModel::JointWeight(vertices[i].joints.x, vertices[i].weights.x)); +                weight_list.push_back(LLModel::JointWeight(vertices[i].joints.y, vertices[i].weights.y)); +                weight_list.push_back(LLModel::JointWeight(vertices[i].joints.z, vertices[i].weights.z)); +                weight_list.push_back(LLModel::JointWeight(vertices[i].joints.w, vertices[i].weights.w)); + +                std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater()); + +                 +                std::vector<LLModel::JointWeight> wght; +                F32                               total = 0.f; + +                for (U32 i = 0; i < llmin((U32)4, (U32)weight_list.size()); ++i) +                { // take up to 4 most significant weights +                    // Ported from the DAE loader - however, GLTF right now only supports up to four weights per vertex. +                    if (weight_list[i].mWeight > 0.f)                      { -                        auto ujoint = glm::unpackUint4x8((U32)(prim.mJoints[i] & 0xFFFFFFFF)); -                        joint = glm::u16vec4(ujoint.x, ujoint.y, ujoint.z, ujoint.w); +                        wght.push_back(weight_list[i]); +                        total += weight_list[i].mWeight;                      } -                    else if (componentType == LL::GLTF::Accessor::ComponentType::UNSIGNED_SHORT) +                } + +                F32 scale = 1.f / total; +                if (scale != 1.f) +                { // normalize weights +                    for (U32 i = 0; i < wght.size(); ++i)                      { -                        joint = glm::unpackUint4x16(prim.mJoints[i]); +                        wght[i].mWeight *= scale;                      } - -                    // Look up the joint index in the skin -                    auto jointIndex0 = skin.mJoints[joint.x]; -                    auto jointIndex1 = skin.mJoints[joint.y]; -                    auto jointIndex2 = skin.mJoints[joint.z]; -                    auto jointIndex3 = skin.mJoints[joint.w]; - -                    // Get the nodes for these joints. -                    auto node0 = mGLTFAsset.mNodes[jointIndex0]; -                    auto node1 = mGLTFAsset.mNodes[jointIndex1]; -                    auto node2 = mGLTFAsset.mNodes[jointIndex2]; -                    auto node3 = mGLTFAsset.mNodes[jointIndex3]; -                  } + +                pModel->mSkinWeights[LLVector3(vertices[i].position)] = wght;              }              face.fillFromLegacyData(faceVertices, indices); diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index 9d0560de63..519f2d8a07 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -144,6 +144,8 @@ class LLGLTFLoader : public LLModelLoader          glm::vec3 position;          glm::vec3 normal;          glm::vec2 uv0; +        glm::u16vec4 joints; +        glm::vec4 weights;      };  protected: | 
