From 8c0163bcb48df56112a625550d411741c20c5846 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Wed, 13 Apr 2022 12:32:58 -0600 Subject: SL-17214 initial loader class skeleton --- indra/llprimitive/llgltfloader.h | 207 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 indra/llprimitive/llgltfloader.h (limited to 'indra/llprimitive/llgltfloader.h') diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h new file mode 100644 index 0000000000..9bffeef4ab --- /dev/null +++ b/indra/llprimitive/llgltfloader.h @@ -0,0 +1,207 @@ +/** + * @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 "llmodelloader.h" + +typedef struct // gltf sampler +{ // 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; // seen 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 +} gltf_sampler; + +typedef struct // gltf image +{ // Note that glTF images are defined with row 0 at the top + 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 +} gltf_image; + +typedef struct // texture +{ + U32 image_idx; + U32 sampler_idx; +} gltf_texture; + + +// TODO: 2022-05 DJH add UUIDs for each texture +typedef struct // gltf_pbrMR_material +{ + // scalar values + LLColor4 baseColor; // linear encoding. Multiplied with vertex color, if present. + double metalness; + double roughness; + + // textures + U32 baseColorTexIdx; // always sRGB encoded + U32 baseColorTexCoordIdx; + + U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel + U32 metalRoughTexCoordIdx; +} gltf_pbr; + +typedef struct // render material +{ + std::string name; + + // scalar values + 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; + + // textures + U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0) + U32 normalTexCoordIdx; + + U32 occlusionTexIdx; // linear, occlusion in R channel, 0 meaning fully occluded, 1 meaning not occluded + U32 occlusionTexCoordIdx; + + U32 emissiveColorTexIdx; // always stored as sRGB, in nits (candela / meter^2) + U32 emissiveColorTexCoordIdx; + + // TODO: Add traditional (diffuse, normal, specular) UUIDs here, or add this struct to LL_TextureEntry?? + + bool hasPBR; + gltf_pbr pbr; + +} gltf_render_material; + +typedef struct // gltf_mesh +{ + std::string name; + + // TODO DJH 2022-04 + +} gltf_mesh; + +class LLGLTFLoader : public LLModelLoader +{ + public: + typedef std::map material_map; + typedef void gltfElement; // TBD + typedef void GLTF; // TBD + + // typedef std::map > > gltf_model_map; + // gltf_model_map mModelsMap; + + 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: + 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: + U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels +// bool mPreprocessGLTF; + + bool parseMeshes(); + void uploadMeshes(); + bool parseMaterials(); + void uploadMaterials(); + bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh); + + /* + 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 adaaccd3d74dd05b596693ef7de90aeef20b5f9d Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 17 May 2022 15:54:00 -0600 Subject: SL-17214 additional glTF validation, remove dead code from DAE loader --- indra/llprimitive/llgltfloader.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'indra/llprimitive/llgltfloader.h') diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 9bffeef4ab..08e9836d07 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -27,8 +27,9 @@ #ifndef LL_LLGLTFLoader_H #define LL_LLGLTFLoader_H -#include "tinygltf\tiny_gltf.h" +#include "tinygltf/tiny_gltf.h" +#include "llglheaders.h" #include "llmodelloader.h" typedef struct // gltf sampler @@ -74,6 +75,8 @@ typedef struct // gltf_pbrMR_material U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel U32 metalRoughTexCoordIdx; + + bool hasBaseTex, hasMRTex; } gltf_pbr; typedef struct // render material @@ -100,6 +103,7 @@ typedef struct // render material // TODO: Add traditional (diffuse, normal, specular) UUIDs here, or add this struct to LL_TextureEntry?? bool hasPBR; + bool hasNormalTex, hasOcclusionTex, hasEmissiveTex; gltf_pbr pbr; } gltf_render_material; -- cgit v1.2.3 From c9ebb970ee916ace16e88508dc1a178336a91d52 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Wed, 1 Jun 2022 14:37:20 -0600 Subject: SL-17214 re-work gltf data organization --- indra/llprimitive/llgltfloader.h | 70 ++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 38 deletions(-) (limited to 'indra/llprimitive/llgltfloader.h') diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 08e9836d07..24496f6324 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -32,19 +32,21 @@ #include "llglheaders.h" #include "llmodelloader.h" +// gltf_* structs are temporary, used to organize the subset of data that eventually goes into the material LLSD + typedef struct // gltf sampler { // 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; // seen in some sample files, but not part of glTF 2.0 spec. Ignored. + //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 } gltf_sampler; typedef struct // gltf image -{ // Note that glTF images are defined with row 0 at the top +{ // 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; @@ -56,34 +58,19 @@ typedef struct // gltf image typedef struct // texture { - U32 image_idx; - U32 sampler_idx; + U32 imageIdx; + U32 samplerIdx; + LLUUID imageUuid = LLUUID::null; } gltf_texture; - -// TODO: 2022-05 DJH add UUIDs for each texture -typedef struct // gltf_pbrMR_material -{ - // scalar values - LLColor4 baseColor; // linear encoding. Multiplied with vertex color, if present. - double metalness; - double roughness; - - // textures - U32 baseColorTexIdx; // always sRGB encoded - U32 baseColorTexCoordIdx; - - U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel - U32 metalRoughTexCoordIdx; - - bool hasBaseTex, hasMRTex; -} gltf_pbr; - typedef struct // render material { 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) @@ -91,20 +78,26 @@ typedef struct // render material double alphaMask; // textures - U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0) - U32 normalTexCoordIdx; - - U32 occlusionTexIdx; // linear, occlusion in R channel, 0 meaning fully occluded, 1 meaning not occluded - U32 occlusionTexCoordIdx; - - U32 emissiveColorTexIdx; // always stored as sRGB, in nits (candela / meter^2) - U32 emissiveColorTexCoordIdx; + 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 hasNormalTex, hasOcclusionTex, hasEmissiveTex; - gltf_pbr pbr; + bool hasBaseTex, hasMRTex, hasNormalTex, hasOcclusionTex, hasEmissiveTex; + + // This field is populated after upload + LLUUID material_uuid = LLUUID::null; } gltf_render_material; @@ -112,7 +105,7 @@ typedef struct // gltf_mesh { std::string name; - // TODO DJH 2022-04 + // TODO add mesh import DJH 2022-04 } gltf_mesh; @@ -157,16 +150,17 @@ protected: std::vector mSamplers; private: - U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels -// bool mPreprocessGLTF; - bool parseMeshes(); void uploadMeshes(); bool parseMaterials(); void uploadMaterials(); bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh); + LLUUID imageBufferToTextureUUID(const gltf_texture& tex); + + U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels + // bool mPreprocessGLTF; - /* + /* Inherited from dae loader - unknown how useful here void processElement(gltfElement *element, bool &badElement, GLTF *gltf); void processGltfModel(LLModel *model, GLTF *gltf, gltfElement *pRoot, gltfMesh *mesh, gltfSkin *skin); -- cgit v1.2.3 From d3219f57c12ec29025e5c9c68b2cf90d49258672 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 7 Jun 2022 14:42:18 -0600 Subject: SL-17214 remove some dae clutter from gltf header --- indra/llprimitive/llgltfloader.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'indra/llprimitive/llgltfloader.h') diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 24496f6324..9ee816e24e 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -75,7 +75,7 @@ typedef struct // render material 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; + double alphaMask; // alpha cut-off // textures U32 baseColorTexIdx; // always sRGB encoded @@ -113,11 +113,6 @@ class LLGLTFLoader : public LLModelLoader { public: typedef std::map material_map; - typedef void gltfElement; // TBD - typedef void GLTF; // TBD - - // typedef std::map > > gltf_model_map; - // gltf_model_map mModelsMap; LLGLTFLoader(std::string filename, S32 lod, @@ -160,7 +155,8 @@ private: U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels // bool mPreprocessGLTF; - /* Inherited from dae loader - unknown how useful here + /* 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); -- cgit v1.2.3 From 125b099298652347991c521703109e12bccdd47e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 9 Jun 2022 11:02:21 -0500 Subject: VS2019 build fix --- indra/llprimitive/llgltfloader.h | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'indra/llprimitive/llgltfloader.h') diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 9ee816e24e..91389b5845 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -34,8 +34,10 @@ // gltf_* structs are temporary, used to organize the subset of data that eventually goes into the material LLSD -typedef struct // gltf sampler -{ // Uses GL enums +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 @@ -43,10 +45,11 @@ typedef struct // gltf sampler //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 -} gltf_sampler; +}; -typedef struct // gltf image -{ // Note that glTF images are defined with row 0 at the top (opposite of OpenGL) +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; @@ -54,17 +57,19 @@ typedef struct // gltf image 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 -} gltf_image; +}; -typedef struct // texture +class gltf_texture { +public: U32 imageIdx; U32 samplerIdx; LLUUID imageUuid = LLUUID::null; -} gltf_texture; +}; -typedef struct // render material +class gltf_render_material { +public: std::string name; // scalar values @@ -99,15 +104,16 @@ typedef struct // render material // This field is populated after upload LLUUID material_uuid = LLUUID::null; -} gltf_render_material; +}; -typedef struct // gltf_mesh +class gltf_mesh { +public: std::string name; // TODO add mesh import DJH 2022-04 -} gltf_mesh; +}; class LLGLTFLoader : public LLModelLoader { -- cgit v1.2.3 From 0fe39a1f3f64c336ccbf806e89b62d158d1da110 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Thu, 23 Jun 2022 18:07:10 -0700 Subject: Correcting windows specific filesystem issues and removing unused DAE code in llgltfloader.cpp from SL-17214 --- indra/llprimitive/llgltfloader.h | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/llprimitive/llgltfloader.h') diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 91389b5845..b4d6ca1940 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -158,7 +158,6 @@ private: bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh); LLUUID imageBufferToTextureUUID(const gltf_texture& tex); - U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels // bool mPreprocessGLTF; /* Below inherited from dae loader - unknown if/how useful here -- cgit v1.2.3