diff options
| author | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2025-04-08 13:51:21 -0400 | 
|---|---|---|
| committer | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2025-04-08 13:51:21 -0400 | 
| commit | c8499b7f01ac3f46f0764ea8195c30a4a2ec27a8 (patch) | |
| tree | f1175d186cbdd87c0afe13498ba01d46ae56bf92 /indra/newview/gltf/llgltfloader.h | |
| parent | 3c9bb9bfe5aa178141c381cfac066fd31a7252b4 (diff) | |
GLTF WIP.  Still working on getting transforms working proper and need to figure out our indices.
Diffstat (limited to 'indra/newview/gltf/llgltfloader.h')
| -rw-r--r-- | indra/newview/gltf/llgltfloader.h | 209 | 
1 files changed, 209 insertions, 0 deletions
| 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<std::string, LLImportMaterial> 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<std::string, std::string> &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<gltf_mesh>              mMeshes; +    std::vector<gltf_render_material>   mMaterials; + +    std::vector<gltf_texture>           mTextures; +    std::vector<gltf_image>             mImages; +    std::vector<gltf_sampler>           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<std::string, LLMatrix4> &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<LLModel *> &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 | 
