diff options
| author | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2025-05-04 23:40:10 -0400 | 
|---|---|---|
| committer | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2025-05-04 23:40:10 -0400 | 
| commit | dd74b361e35a4e2516fee0b16ca0acf00da58547 (patch) | |
| tree | c9eca3d417674b8cb9ba1f8b3a22f862c13a1f24 | |
| parent | e87c62940656aa740ddfa20bb2eed7a13cdb59c7 (diff) | |
Fix import rotation and UVs
| -rw-r--r-- | indra/llprimitive/llmodelloader.h | 1 | ||||
| -rw-r--r-- | indra/newview/gltf/llgltfloader.cpp | 241 | ||||
| -rw-r--r-- | indra/newview/gltf/llgltfloader.h | 2 | 
3 files changed, 35 insertions, 209 deletions
diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 530e61e2b8..2dd0058ba6 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -111,6 +111,7 @@ public:      bool mCacheOnlyHitIfRigged; // ignore cached SLM if it does not contain rig info (and we want rig info)      model_list      mModelList; +    // The scene is pretty much what ends up getting loaded for upload.  Basically assign things to this guy if you want something uploaded.      scene               mScene;      typedef std::queue<LLPointer<LLModel> > model_queue; diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp index 3f58f512e5..3c723c7acd 100644 --- a/indra/newview/gltf/llgltfloader.cpp +++ b/indra/newview/gltf/llgltfloader.cpp @@ -153,15 +153,20 @@ bool LLGLTFLoader::parseMeshes()              {                  LLModel* pModel = new LLModel(volume_params, 0.f);                  auto mesh = mGLTFAsset.mMeshes[meshidx]; -                if (populateModelFromMesh(pModel, mesh, mats) && (LLModel::NO_ERRORS == pModel->getStatus()) && validate_model(pModel)) +                if (populateModelFromMesh(pModel, mesh, node, mats) && (LLModel::NO_ERRORS == pModel->getStatus()) && validate_model(pModel))                  {                      mModelList.push_back(pModel);                      LLMatrix4 saved_transform = mTransform; -                      LLMatrix4 gltf_transform = LLMatrix4(glm::value_ptr(node.mMatrix)); +                      mTransform *= gltf_transform;                      mTransform.condition(); +                    // GLTF is +Y up, SL is +Z up +                    LLMatrix4 rotation; +                    rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f); +                    mTransform *= rotation; +                      transformation = mTransform;                      // adjust the transformation to compensate for mesh normalization                      LLVector3 mesh_scale_vector; @@ -206,7 +211,7 @@ bool LLGLTFLoader::parseMeshes()      return true;  } -bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map &mats) +bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh& mesh, const LL::GLTF::Node& node, material_map& mats)  {      pModel->mLabel = mesh.mName;      pModel->ClearFacesAndMaterials(); @@ -222,10 +227,10 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &              // count. Just go ahead and populate faces direct from the GLTF primitives here. -Geenz 2025-04-07              LLVolumeFace                          face;              LLVolumeFace::VertexMapData::PointMap point_map; - +                          std::vector<GLTFVertex> vertices;              std::vector<U16>        indices; - +                          LLImportMaterial impMat;              LL::GLTF::Material* material = nullptr; @@ -240,7 +245,7 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &                  GLTFVertex vert;                  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]); +                vert.uv0      = glm::vec2(prim.mTexCoords0[i][0],-prim.mTexCoords0[i][1]);                  vertices.push_back(vert);              } @@ -250,12 +255,29 @@ 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; -                LLVector4a               position = LLVector4a(vertices[i].position.x, vertices[i].position.y, vertices[i].position.z); -                LLVector4a               normal   = LLVector4a(vertices[i].normal.x, vertices[i].normal.y, vertices[i].normal.z); + +                if (vertices[i].position.x > max.x) +                    max.x = vertices[i].position.x; +                if (vertices[i].position.y > max.y) +                    max.y = vertices[i].position.y; +                if (vertices[i].position.z > max.z) +                    max.z = vertices[i].position.z; + +                 +                if (vertices[i].position.x < min.x) +                    min.x = vertices[i].position.x; +                if (vertices[i].position.y < min.y) +                    min.y = vertices[i].position.y; +                if (vertices[i].position.z < min.z) +                    min.z = vertices[i].position.z; + +                LLVector4a position = LLVector4a(vertices[i].position.x, vertices[i].position.y, vertices[i].position.z); +                LLVector4a normal = LLVector4a(vertices[i].normal.x, vertices[i].normal.y, vertices[i].normal.z);                  vert.setPosition(position);                  vert.setNormal(normal);                  vert.mTexCoord = LLVector2(vertices[i].uv0.x, vertices[i].uv0.y); @@ -263,6 +285,8 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &              }              face.fillFromLegacyData(faceVertices, indices); +            face.mExtents[0] = LLVector4a(min.x, min.y, min.z, 0); +            face.mExtents[1] = LLVector4a(max.x, max.y, max.z, 0);              pModel->getVolumeFaces().push_back(face);              pModel->getMaterialList().push_back("mat" + std::to_string(prim.mMaterial)); @@ -280,205 +304,6 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &      return true;  } -    /* -LLModel::EModelStatus loadFaceFromGLTFModel(LLModel* pModel, const LL::GLTF::Mesh& mesh, material_map& mats, LLSD& log_msg) -{ -    LLVolumeFace                          face; -    std::vector<LLVolumeFace::VertexData> verts; -    std::vector<U16>                      indices; - -    S32 pos_offset  = -1; -    S32 tc_offset   = -1; -    S32 norm_offset = -1; - -    auto pos_source = mesh.mPrimitives[0].mPositions; -    auto tc_source  = mesh.mPrimitives[0].mNormals; -    auto norm_source = mesh.mPrimitives[0].mTexCoords0; - -    S32 idx_stride = 0; - -    if (pos_source.size() > USHRT_MAX) -    { -        LL_WARNS() << "Unable to process mesh due to 16-bit index limits; invalid model;  invalid model." << LL_ENDL; -        LLSD args; -        args["Message"] = "ParsingErrorBadElement"; -        log_msg.append(args); -        return LLModel::BAD_ELEMENT; - -    } - -    std::vector<U32> idx = mesh.mPrimitives[0].mIndexArray; - -    domListOfFloats  dummy; -    domListOfFloats& v  = pos_source ? pos_source->getFloat_array()->getValue() : dummy; -    domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy; -    domListOfFloats& n  = norm_source ? norm_source->getFloat_array()->getValue() : dummy; - -    if (pos_source.size() == 0) -    { -        return LLModel::BAD_ELEMENT; -    } - -    // VFExtents change -    face.mExtents[0].set(pos_source[0][0], pos_source[0][1], pos_source[0][2]); -    face.mExtents[1].set(pos_source[0][0], pos_source[0][1], pos_source[0][2]); - -    LLVolumeFace::VertexMapData::PointMap point_map; - -    if (idx_stride <= 0 || (pos_source && pos_offset >= idx_stride) || (tc_source && tc_offset >= idx_stride) || -        (norm_source && norm_offset >= idx_stride)) -    { -        // Looks like these offsets should fit inside idx_stride -        // Might be good idea to also check idx.getCount()%idx_stride != 0 -        LL_WARNS() << "Invalid pos_offset " << pos_offset << ", tc_offset " << tc_offset << " or norm_offset " << norm_offset << LL_ENDL; -        return LLModel::BAD_ELEMENT; -    } - -    for (U32 i = 0; i < idx.getCount(); i += idx_stride) -    { -        LLVolumeFace::VertexData cv; -        if (pos_source) -        { -            cv.setPosition( -                LLVector4a((F32)v[idx[i + pos_offset] * 3 + 0], (F32)v[idx[i + pos_offset] * 3 + 1], (F32)v[idx[i + pos_offset] * 3 + 2])); -        } - -        if (tc_source) -        { -            cv.mTexCoord.setVec((F32)tc[idx[i + tc_offset] * 2 + 0], (F32)tc[idx[i + tc_offset] * 2 + 1]); -        } - -        if (norm_source) -        { -            cv.setNormal(LLVector4a((F32)n[idx[i + norm_offset] * 3 + 0], -                                    (F32)n[idx[i + norm_offset] * 3 + 1], -                                    (F32)n[idx[i + norm_offset] * 3 + 2])); -        } - -        bool found = false; - -        LLVolumeFace::VertexMapData::PointMap::iterator point_iter; -        point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr())); - -        if (point_iter != point_map.end()) -        { -            for (U32 j = 0; j < point_iter->second.size(); ++j) -            { -                // We have a matching loc -                // -                if ((point_iter->second)[j] == cv) -                { -                    U16 shared_index = (point_iter->second)[j].mIndex; - -                    // Don't share verts within the same tri, degenerate -                    // -                    U32 indx_size     = static_cast<U32>(indices.size()); -                    U32 verts_new_tri = indx_size % 3; -                    if ((verts_new_tri < 1 || indices[indx_size - 1] != shared_index) && -                        (verts_new_tri < 2 || indices[indx_size - 2] != shared_index)) -                    { -                        found = true; -                        indices.push_back(shared_index); -                    } -                    break; -                } -            } -        } - -        if (!found) -        { -            // VFExtents change -            update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition()); -            verts.push_back(cv); -            if (verts.size() >= 65535) -            { -                // llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL; -                return LLModel::VERTEX_NUMBER_OVERFLOW; -            } -            U16 index = (U16)(verts.size() - 1); -            indices.push_back(index); - -            LLVolumeFace::VertexMapData d; -            d.setPosition(cv.getPosition()); -            d.mTexCoord = cv.mTexCoord; -            d.setNormal(cv.getNormal()); -            d.mIndex = index; -            if (point_iter != point_map.end()) -            { -                point_iter->second.push_back(d); -            } -            else -            { -                point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d); -            } -        } - -        if (indices.size() % 3 == 0 && verts.size() >= 65532) -        { -            std::string material; - -            if (tri->getMaterial()) -            { -                material = std::string(tri->getMaterial()); -            } - -            materials.push_back(material); -            face_list.push_back(face); -            face_list.rbegin()->fillFromLegacyData(verts, indices); -            LLVolumeFace& new_face = *face_list.rbegin(); -            if (!norm_source) -            { -                // ll_aligned_free_16(new_face.mNormals); -                new_face.mNormals = NULL; -            } - -            if (!tc_source) -            { -                // ll_aligned_free_16(new_face.mTexCoords); -                new_face.mTexCoords = NULL; -            } - -            face = LLVolumeFace(); -            // VFExtents change -            face.mExtents[0].set((F32)v[0], (F32)v[1], (F32)v[2]); -            face.mExtents[1].set((F32)v[0], (F32)v[1], (F32)v[2]); - -            verts.clear(); -            indices.clear(); -            point_map.clear(); -        } -    } - -    if (!verts.empty()) -    { -        std::string material; - -        if (tri->getMaterial()) -        { -            material = std::string(tri->getMaterial()); -        } - -        materials.push_back(material); -        face_list.push_back(face); - -        face_list.rbegin()->fillFromLegacyData(verts, indices); -        LLVolumeFace& new_face = *face_list.rbegin(); -        if (!norm_source) -        { -            // ll_aligned_free_16(new_face.mNormals); -            new_face.mNormals = NULL; -        } - -        if (!tc_source) -        { -            // ll_aligned_free_16(new_face.mTexCoords); -            new_face.mTexCoords = NULL; -        } -    } - -    return LLModel::NO_ERRORS; -} -*/  bool LLGLTFLoader::parseMaterials()  {      return true; diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index cfb545be6f..044cc262d7 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -165,7 +165,7 @@ private:      void uploadMeshes();      bool parseMaterials();      void uploadMaterials(); -    bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map& mats); +    bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats);      LLUUID imageBufferToTextureUUID(const gltf_texture& tex);      //    bool mPreprocessGLTF;  | 
