From c8499b7f01ac3f46f0764ea8195c30a4a2ec27a8 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 8 Apr 2025 13:51:21 -0400 Subject: GLTF WIP. Still working on getting transforms working proper and need to figure out our indices. --- indra/newview/gltf/llgltfloader.h | 209 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 indra/newview/gltf/llgltfloader.h (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h new file mode 100644 index 0000000000..3b7147f588 --- /dev/null +++ b/indra/newview/gltf/llgltfloader.h @@ -0,0 +1,209 @@ +/** + * @file LLGLTFLoader.h + * @brief LLGLTFLoader class definition + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLGLTFLoader_H +#define LL_LLGLTFLoader_H + +#include "tinygltf/tiny_gltf.h" + +#include "asset.h" + +#include "llglheaders.h" +#include "llmodelloader.h" + +// gltf_* structs are temporary, used to organize the subset of data that eventually goes into the material LLSD + +class gltf_sampler +{ +public: + // Uses GL enums + S32 minFilter; // GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR or GL_LINEAR_MIPMAP_LINEAR + S32 magFilter; // GL_NEAREST or GL_LINEAR + S32 wrapS; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT + S32 wrapT; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT + //S32 wrapR; // Found in some sample files, but not part of glTF 2.0 spec. Ignored. + std::string name; // optional, currently unused + // extensions and extras are sampler optional fields that we don't support - at least initially +}; + +class gltf_image +{ +public:// Note that glTF images are defined with row 0 at the top (opposite of OpenGL) + U8* data; // ptr to decoded image data + U32 size; // in bytes, regardless of channel width + U32 width; + U32 height; + U32 numChannels; // range 1..4 + U32 bytesPerChannel; // converted from gltf "bits", expects only 8, 16 or 32 as input + U32 pixelType; // one of (TINYGLTF_COMPONENT_TYPE)_UNSIGNED_BYTE, _UNSIGNED_SHORT, _UNSIGNED_INT, or _FLOAT +}; + +class gltf_texture +{ +public: + U32 imageIdx; + U32 samplerIdx; + LLUUID imageUuid = LLUUID::null; +}; + +class gltf_render_material +{ +public: + std::string name; + + // scalar values + LLColor4 baseColor; // linear encoding. Multiplied with vertex color, if present. + double metalness; + double roughness; + double normalScale; // scale applies only to X,Y components of normal + double occlusionScale; // strength multiplier for occlusion + LLColor4 emissiveColor; // emissive mulitiplier, assumed linear encoding (spec 2.0 is silent) + std::string alphaMode; // "OPAQUE", "MASK" or "BLEND" + double alphaMask; // alpha cut-off + + // textures + U32 baseColorTexIdx; // always sRGB encoded + U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel + U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0) + U32 occlusionTexIdx; // linear, occlusion in R channel, 0 meaning fully occluded, 1 meaning not occluded + U32 emissiveTexIdx; // always stored as sRGB, in nits (candela / meter^2) + + // texture coordinates + U32 baseColorTexCoords; + U32 metalRoughTexCoords; + U32 normalTexCoords; + U32 occlusionTexCoords; + U32 emissiveTexCoords; + + // TODO: Add traditional (diffuse, normal, specular) UUIDs here, or add this struct to LL_TextureEntry?? + + bool hasPBR; + bool hasBaseTex, hasMRTex, hasNormalTex, hasOcclusionTex, hasEmissiveTex; + + // This field is populated after upload + LLUUID material_uuid = LLUUID::null; + +}; + +class gltf_mesh +{ +public: + std::string name; + + // TODO add mesh import DJH 2022-04 + +}; + +class LLGLTFLoader : public LLModelLoader +{ + public: + typedef std::map material_map; + + LLGLTFLoader(std::string filename, + S32 lod, + LLModelLoader::load_callback_t load_cb, + LLModelLoader::joint_lookup_func_t joint_lookup_func, + LLModelLoader::texture_load_func_t texture_load_func, + LLModelLoader::state_callback_t state_cb, + void * opaque_userdata, + JointTransformMap & jointTransformMap, + JointNameSet & jointsFromNodes, + std::map &jointAliasMap, + U32 maxJointsPerMesh, + U32 modelLimit); //, + //bool preprocess ); + virtual ~LLGLTFLoader(); + + virtual bool OpenFile(const std::string &filename); + +protected: + LL::GLTF::Asset mGLTFAsset; + tinygltf::Model mGltfModel; + bool mGltfLoaded; + bool mMeshesLoaded; + bool mMaterialsLoaded; + + std::vector mMeshes; + std::vector mMaterials; + + std::vector mTextures; + std::vector mImages; + std::vector mSamplers; + +private: + bool parseMeshes(); + void uploadMeshes(); + bool parseMaterials(); + void uploadMaterials(); + bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map& mats); + LLUUID imageBufferToTextureUUID(const gltf_texture& tex); + + // bool mPreprocessGLTF; + + /* Below inherited from dae loader - unknown if/how useful here + + void processElement(gltfElement *element, bool &badElement, GLTF *gltf); + void processGltfModel(LLModel *model, GLTF *gltf, gltfElement *pRoot, gltfMesh *mesh, gltfSkin *skin); + + material_map getMaterials(LLModel *model, gltfInstance_geometry *instance_geo, GLTF *gltf); + LLImportMaterial profileToMaterial(gltfProfile_COMMON *material, GLTF *gltf); + LLColor4 getGltfColor(gltfElement *element); + + gltfElement *getChildFromElement(gltfElement *pElement, std::string const &name); + + bool isNodeAJoint(gltfNode *pNode); + void processJointNode(gltfNode *pNode, std::map &jointTransforms); + void extractTranslation(gltfTranslate *pTranslate, LLMatrix4 &transform); + void extractTranslationViaElement(gltfElement *pTranslateElement, LLMatrix4 &transform); + void extractTranslationViaSID(gltfElement *pElement, LLMatrix4 &transform); + void buildJointToNodeMappingFromScene(gltfElement *pRoot); + void processJointToNodeMapping(gltfNode *pNode); + void processChildJoints(gltfNode *pParentNode); + + bool verifyCount(int expected, int result); + + // Verify that a controller matches vertex counts + bool verifyController(gltfController *pController); + + static bool addVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh, LLSD &log_msg); + static bool createVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh); + + static LLModel *loadModelFromGltfMesh(gltfMesh *mesh); + + // Loads a mesh breaking it into one or more models as necessary + // to get around volume face limitations while retaining >8 materials + // + bool loadModelsFromGltfMesh(gltfMesh *mesh, std::vector &models_out, U32 submodel_limit); + + static std::string getElementLabel(gltfElement *element); + static size_t getSuffixPosition(std::string label); + static std::string getLodlessLabel(gltfElement *element); + + static std::string preprocessGLTF(std::string filename); + */ + +}; +#endif // LL_LLGLTFLLOADER_H -- cgit v1.2.3 From f6b066073e9a6318dc9ebac4b0137b81e2982f14 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 28 Apr 2025 03:33:03 -0400 Subject: Cursed stuff! --- indra/newview/gltf/llgltfloader.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index 3b7147f588..cfb545be6f 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -139,6 +139,13 @@ class LLGLTFLoader : public LLModelLoader virtual bool OpenFile(const std::string &filename); + struct GLTFVertex + { + glm::vec3 position; + glm::vec3 normal; + glm::vec2 uv0; + }; + protected: LL::GLTF::Asset mGLTFAsset; tinygltf::Model mGltfModel; -- cgit v1.2.3 From 008f89f7e9698028e8beaa42a64428909271ebf3 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Sun, 4 May 2025 19:05:34 -0400 Subject: More fixes - still a bit hacky but getting there. --- indra/newview/gltf/llgltfloader.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index cfb545be6f..32275d168d 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -168,6 +168,8 @@ private: bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map& mats); LLUUID imageBufferToTextureUUID(const gltf_texture& tex); + void processPrimitive(const LL::GLTF::Primitive& primitive, const LL::GLTF::Node& node); + // bool mPreprocessGLTF; /* Below inherited from dae loader - unknown if/how useful here -- cgit v1.2.3 From e87c62940656aa740ddfa20bb2eed7a13cdb59c7 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Sun, 4 May 2025 21:06:10 -0400 Subject: Transforms transmigrofied --- indra/newview/gltf/llgltfloader.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index 32275d168d..cfb545be6f 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -168,8 +168,6 @@ private: bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map& mats); LLUUID imageBufferToTextureUUID(const gltf_texture& tex); - void processPrimitive(const LL::GLTF::Primitive& primitive, const LL::GLTF::Node& node); - // bool mPreprocessGLTF; /* Below inherited from dae loader - unknown if/how useful here -- cgit v1.2.3 From dd74b361e35a4e2516fee0b16ca0acf00da58547 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Sun, 4 May 2025 23:40:10 -0400 Subject: Fix import rotation and UVs --- indra/newview/gltf/llgltfloader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/gltf/llgltfloader.h') 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; -- cgit v1.2.3 From 629e56d864726eaa0340be220be8c3e3f500ca32 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 5 May 2025 05:06:46 -0400 Subject: Make sure transformation matricies are actually setup. Start getting joints in. --- indra/newview/gltf/llgltfloader.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index 044cc262d7..9d0560de63 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -166,6 +166,7 @@ private: bool parseMaterials(); void uploadMaterials(); bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats); + void populateJointFromSkin(const LL::GLTF::Skin& skin); LLUUID imageBufferToTextureUUID(const gltf_texture& tex); // bool mPreprocessGLTF; -- cgit v1.2.3 From 2efe514f14a0f0b405599301a14413edfce873ee Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 14 May 2025 10:33:01 -0400 Subject: Make pulling weights per vertex. --- indra/newview/gltf/llgltfloader.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/gltf/llgltfloader.h') 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: -- cgit v1.2.3 From b572bf75968005388fab8ad0b3259d417c7f224c Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 14 May 2025 19:59:20 +0300 Subject: Improve mesh scaling --- indra/newview/gltf/llgltfloader.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index 519f2d8a07..bfcdccac00 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -167,7 +167,8 @@ private: void uploadMeshes(); bool parseMaterials(); void uploadMaterials(); - bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats); + bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats, + const F32 scale_factor = 1.0f, const LLVector3& center_offset = LLVector3()); void populateJointFromSkin(const LL::GLTF::Skin& skin); LLUUID imageBufferToTextureUUID(const gltf_texture& tex); -- cgit v1.2.3 From f5d4d3f86224df61bacabf219b6d053bcdebc3ef Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 22 May 2025 19:53:35 +0300 Subject: #4109 Improve handling of GLTF transform hierarchy --- indra/newview/gltf/llgltfloader.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index bfcdccac00..4d02909f72 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -167,6 +167,7 @@ private: void uploadMeshes(); bool parseMaterials(); void uploadMaterials(); + void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform); bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats, const F32 scale_factor = 1.0f, const LLVector3& center_offset = LLVector3()); void populateJointFromSkin(const LL::GLTF::Skin& skin); -- cgit v1.2.3 From 4faebc08301f57e5191d29010c00e72748a45323 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Sat, 24 May 2025 19:45:52 +0300 Subject: #4109 Remove workaround code --- indra/newview/gltf/llgltfloader.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index 4d02909f72..fac5b719fb 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -168,8 +168,7 @@ private: bool parseMaterials(); void uploadMaterials(); void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform); - bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats, - const F32 scale_factor = 1.0f, const LLVector3& center_offset = LLVector3()); + bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats); void populateJointFromSkin(const LL::GLTF::Skin& skin); LLUUID imageBufferToTextureUUID(const gltf_texture& tex); -- cgit v1.2.3 From b423900792aca2e094fac85f9aeb34b26f9c2109 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Sun, 25 May 2025 19:28:24 +0300 Subject: #4105 Fix duplicate GLTF model instances causing upload errors --- indra/newview/gltf/llgltfloader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index fac5b719fb..69289aabce 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -168,7 +168,7 @@ private: bool parseMaterials(); void uploadMaterials(); void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform); - bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats); + bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats, S32 instance_count); void populateJointFromSkin(const LL::GLTF::Skin& skin); LLUUID imageBufferToTextureUUID(const gltf_texture& tex); -- cgit v1.2.3 From 078cc9b0c1dc00b55bad9b3152651a66e8e2e79f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 26 May 2025 21:27:09 +0300 Subject: #4080 Rigged mesh support #5 --- indra/newview/gltf/llgltfloader.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index 69289aabce..d0f761df2c 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -167,9 +167,11 @@ private: void uploadMeshes(); bool parseMaterials(); void uploadMaterials(); - void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform); + void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) const; bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats, S32 instance_count); void populateJointFromSkin(const LL::GLTF::Skin& skin); + S32 findValidRootJoint(S32 source_joint, const LL::GLTF::Skin& gltf_skin) const; + S32 findGLTFRootJoint(const LL::GLTF::Skin& gltf_skin) const; // if there are multiple roots, gltf stores them under one commor joint LLUUID imageBufferToTextureUUID(const gltf_texture& tex); // bool mPreprocessGLTF; -- cgit v1.2.3 From 136149d1a196d2c0c15b9977937e64ccd26c1a49 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Fri, 30 May 2025 03:06:33 +0300 Subject: #4191 skip loading model compressed with Draco --- indra/newview/gltf/llgltfloader.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/gltf/llgltfloader.h') diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index d0f761df2c..6e0fe2b32c 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -174,6 +174,8 @@ private: S32 findGLTFRootJoint(const LL::GLTF::Skin& gltf_skin) const; // if there are multiple roots, gltf stores them under one commor joint LLUUID imageBufferToTextureUUID(const gltf_texture& tex); + void notifyUnsupportedExtension(bool unsupported); + // bool mPreprocessGLTF; /* Below inherited from dae loader - unknown if/how useful here -- cgit v1.2.3