diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llmath/v3color.h | 32 | ||||
| -rw-r--r-- | indra/llmath/v4color.h | 29 | ||||
| -rw-r--r-- | indra/llprimitive/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | indra/llprimitive/llgltfmaterial.cpp | 199 | ||||
| -rw-r--r-- | indra/llprimitive/llgltfmaterial.h | 34 | ||||
| -rw-r--r-- | indra/newview/llgltfmateriallist.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/lllocalgltfmaterials.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/lltinygltfhelper.cpp | 65 | ||||
| -rw-r--r-- | indra/newview/lltinygltfhelper.h | 1 | 
9 files changed, 293 insertions, 83 deletions
| diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 0b3b4ea3e1..d925f56e97 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -88,6 +88,16 @@ public:  	const LLColor3&	set(F32 x, F32 y, F32 z);	// Sets LLColor3 to (x, y, z)  	const LLColor3&	set(const LLColor3 &vec);	// Sets LLColor3 to vec  	const LLColor3&	set(const F32 *vec);		// Sets LLColor3 to vec +     +    // set from a vector of unknown type and size +    // may leave some data unmodified +    template<typename T> +    const LLColor3& set(const std::vector<T>& v); + +    // write to a vector of unknown type and size +    // maye leave some data unmodified +    template<typename T> +    void write(std::vector<T>& v) const;  	F32		magVec() const;				// deprecated  	F32		magVecSquared() const;		// deprecated @@ -504,4 +514,26 @@ inline const LLVector3 linearColor3v(const T& a) {      return LLVector3(linearColor3p(a.mV).mV);  } +template<typename T> +const LLColor3& LLColor3::set(const std::vector<T>& v) +{ +    for (S32 i = 0; i < llmin((S32)v.size(), 3); ++i) +    { +        mV[i] = v[i]; +    } + +    return *this; +} + +// write to a vector of unknown type and size +// maye leave some data unmodified +template<typename T> +void LLColor3::write(std::vector<T>& v) const +{ +    for (int i = 0; i < llmin((S32)v.size(), 3); ++i) +    { +        v[i] = mV[i]; +    } +} +  #endif diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index f2863be531..daa61594fb 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -91,6 +91,15 @@ class LLColor4          const LLColor4&	set(const F64 *vec);			// Sets LLColor4 to (double)vec          const LLColor4&	set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. +        // set from a vector of unknown type and size +        // may leave some data unmodified +        template<typename T>  +        const LLColor4& set(const std::vector<T>& v); + +        // write to a vector of unknown type and size +        // maye leave some data unmodified +        template<typename T> +        void write(std::vector<T>& v) const;  		const LLColor4&    setAlpha(F32 a); @@ -690,5 +699,25 @@ inline const LLColor4 linearColor4(const LLColor4 &a)      return linearColor;  } +template<typename T> +const LLColor4& LLColor4::set(const std::vector<T>& v) +{ +    for (S32 i = 0; i < llmin((S32)v.size(), 4); ++i) +    { +        mV[i] = v[i]; +    } + +    return *this; +} + +template<typename T> +void LLColor4::write(std::vector<T>& v) const +{ +    for (int i = 0; i < llmin((S32)v.size(), 4); ++i) +    { +        v[i] = mV[i]; +    } +} +  #endif diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index bb14bb9242..328b22f900 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -33,6 +33,7 @@ include_directories(SYSTEM  set(llprimitive_SOURCE_FILES      lldaeloader.cpp      llgltfloader.cpp +    llgltfmaterial.cpp      llmaterialid.cpp      llmaterial.cpp      llmaterialtable.cpp diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp new file mode 100644 index 0000000000..369a1786a3 --- /dev/null +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -0,0 +1,199 @@ +/** + * @file llgltfmaterial.cpp + * @brief Material 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$ + */ + +#include "linden_common.h" + +#include "llgltfmaterial.h" + +#include "tiny_gltf.h" + +bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg) +{ +    tinygltf::TinyGLTF gltf; +     +    tinygltf::Model model_in; + +    if (gltf.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, json.c_str(), json.length(), "")) +    { +        setFromModel(model_in, 0); + +        //DEBUG generate json and print +        LL_INFOS() << asJSON(true) << LL_ENDL; + +        return true; +    } + +    return false; +} + +std::string LLGLTFMaterial::asJSON(bool prettyprint) const +{ +    tinygltf::TinyGLTF gltf; +    tinygltf::Model model_out; + +    std::ostringstream str; + +    writeToModel(model_out, 0); + +    gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false); + +    return str.str(); +} + +void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) +{ +    if (model.materials.size() <= mat_index) +    { +        return; +    } + +    const tinygltf::Material& material_in = model.materials[mat_index]; + +    // get base color texture +    S32 tex_index = material_in.pbrMetallicRoughness.baseColorTexture.index; +    if (tex_index >= 0) +    { +        mBaseColorId.set(model.images[tex_index].uri); +    } +    else +    { +        mBaseColorId.setNull(); +    } + +    // get normal map +    tex_index = material_in.normalTexture.index; +    if (tex_index >= 0) +    { +        mNormalId.set(model.images[tex_index].uri); +    } +    else +    { +        mNormalId.setNull(); +    } + +    // get metallic-roughness texture +    tex_index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; +    if (tex_index >= 0) +    { +        mMetallicRoughnessId.set(model.images[tex_index].uri); +    } +    else +    { +        mMetallicRoughnessId.setNull(); +    } + +    // get emissive texture +    tex_index = material_in.emissiveTexture.index; +    if (tex_index >= 0) +    { +        mEmissiveId.set(model.images[tex_index].uri); +    } +    else +    { +        mEmissiveId.setNull(); +    } + +    setAlphaMode(material_in.alphaMode); +    mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); + +    mBaseColor.set(material_in.pbrMetallicRoughness.baseColorFactor); +    mEmissiveColor.set(material_in.emissiveFactor); + +    mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f); +    mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f); + +    mDoubleSided = material_in.doubleSided; +} + +void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const +{ +    if (model.materials.size() < mat_index+1) +    { +        model.materials.resize(mat_index + 1); +    } + +    tinygltf::Material& material_out = model.materials[mat_index]; + +    // set base color texture +    if (mBaseColorId.notNull()) +    { +        U32 idx = model.images.size(); +        model.images.resize(idx + 1); +        model.textures.resize(idx + 1); +         +        material_out.pbrMetallicRoughness.baseColorTexture.index = idx; +        model.textures[idx].source = idx; +        model.images[idx].uri = mBaseColorId.asString(); +    } + +    // set normal texture +    if (mNormalId.notNull()) +    { +        U32 idx = model.images.size(); +        model.images.resize(idx + 1); +        model.textures.resize(idx + 1); + +        material_out.normalTexture.index = idx; +        model.textures[idx].source = idx; +        model.images[idx].uri = mNormalId.asString(); +    } +     +    // set metallic-roughness texture +    if (mMetallicRoughnessId.notNull()) +    { +        U32 idx = model.images.size(); +        model.images.resize(idx + 1); +        model.textures.resize(idx + 1); + +        material_out.pbrMetallicRoughness.metallicRoughnessTexture.index = idx; +        model.textures[idx].source = idx; +        model.images[idx].uri = mMetallicRoughnessId.asString(); +    } + +    // set emissive texture +    if (mEmissiveId.notNull()) +    { +        U32 idx = model.images.size(); +        model.images.resize(idx + 1); +        model.textures.resize(idx + 1); + +        material_out.emissiveTexture.index = idx; +        model.textures[idx].source = idx; +        model.images[idx].uri = mEmissiveId.asString(); +    } + +    material_out.alphaMode = getAlphaMode(); +    material_out.alphaCutoff = mAlphaCutoff; +     +    mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); +    mEmissiveColor.write(material_out.emissiveFactor); + +    material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor; +    material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; + +    material_out.doubleSided = mDoubleSided; +} + diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 36636c3b4e..8efcc9d753 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -32,6 +32,13 @@  #include "lluuid.h"  #include "llmd5.h" +#include <string> + +namespace tinygltf +{ +    class Model; +} +  class LLGLTFMaterial : public LLRefCount  {  public: @@ -48,8 +55,8 @@ public:      LLUUID mMetallicRoughnessId;      LLUUID mEmissiveId; -    LLColor4 mBaseColor = LLColor4(1,1,1,1); -    LLColor3 mEmissiveColor = LLColor3(0,0,0); +    LLColor4 mBaseColor = LLColor4(1, 1, 1, 1); +    LLColor3 mEmissiveColor = LLColor3(0, 0, 0);      F32 mMetallicFactor = 0.f;      F32 mRoughnessFactor = 0.f; @@ -63,7 +70,7 @@ public:      {          LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;          LLMD5 md5; -        md5.update((unsigned char*) this, sizeof(this)); +        md5.update((unsigned char*)this, sizeof(this));          md5.finalize();          LLUUID id;          md5.raw_digest(id.mData); @@ -88,7 +95,7 @@ public:          }      } -    const char* getAlphaMode() +    const char* getAlphaMode() const      {          switch (mAlphaMode)          { @@ -97,7 +104,24 @@ public:          default: return "OPAQUE";          }      } -}; +    // set the contents of this LLGLTFMaterial from the given json +    // returns true if successful +    // json - the json text to load from +    // warn_msg - warning message from TinyGLTF if any +    // error_msg - error_msg from TinyGLTF if any +    bool fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg); +    // get the contents of this LLGLTFMaterial as a json string +    std::string asJSON(bool prettyprint = false) const; + +    // initialize from given tinygltf::Model +    // model - the model to reference +    // mat_index - index of material in model's material array +    void setFromModel(const tinygltf::Model& model, S32 mat_index); + +    // write to given tinygltf::Model +    void writeToModel(tinygltf::Model& model, S32 mat_index) const; + +}; diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 9c71f11bbc..24fd623231 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -106,18 +106,9 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)                              {                                  std::string data = asset["data"]; -                                tinygltf::TinyGLTF gltf; -                                tinygltf::TinyGLTF loader; -                                std::string        error_msg; -                                std::string        warn_msg; +                                std::string warn_msg, error_msg; -                                tinygltf::Model model_in; - -                                if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), "")) -                                { -                                    LLTinyGLTFHelper::setFromModel(mat, model_in, 0); -                                } -                                else +                                if (!mat->fromJSON(data, warn_msg, error_msg))                                  {                                      LL_WARNS() << "Failed to decode material asset: " << LL_ENDL;                                      LL_WARNS() << warn_msg << LL_ENDL; diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index 1f16549a47..fe2b7ac816 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -270,7 +270,7 @@ bool LLLocalGLTFMaterial::loadMaterial(LLPointer<LLGLTFMaterial> mat, S32 index)              }              // sets everything, but textures will have inaccurate ids -            LLTinyGLTFHelper::setFromModel(mat, model_in, index); +            mat->setFromModel(model_in, index);              std::string folder = gDirUtilp->getDirName(filename_lc);              tinygltf::Material material_in = model_in.materials[index]; diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index c3dc10c2a0..c80e87652a 100644 --- a/indra/newview/lltinygltfhelper.cpp +++ b/indra/newview/lltinygltfhelper.cpp @@ -122,71 +122,6 @@ void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material,      }  } -void LLTinyGLTFHelper::setFromModel(LLGLTFMaterial* mat, tinygltf::Model& model, S32 mat_index) -{ -    if (model.materials.size() <= mat_index) -    { -        return; -    } - -    tinygltf::Material& material_in = model.materials[mat_index]; - -    // get base color texture -    S32 tex_index = material_in.pbrMetallicRoughness.baseColorTexture.index; -    if (tex_index >= 0) -    { -        mat->mBaseColorId.set(model.images[tex_index].uri); -    } -    else -    { -        mat->mBaseColorId.setNull(); -    } - -    // get normal map -    tex_index = material_in.normalTexture.index; -    if (tex_index >= 0) -    { -        mat->mNormalId.set(model.images[tex_index].uri); -    } -    else -    { -        mat->mNormalId.setNull(); -    } - -    // get metallic-roughness texture -    tex_index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; -    if (tex_index >= 0) -    { -        mat->mMetallicRoughnessId.set(model.images[tex_index].uri); -    } -    else -    { -        mat->mMetallicRoughnessId.setNull(); -    } - -    // get emissive texture -    tex_index = material_in.emissiveTexture.index; -    if (tex_index >= 0) -    { -        mat->mEmissiveId.set(model.images[tex_index].uri); -    } -    else -    { -        mat->mEmissiveId.setNull(); -    } - -    mat->setAlphaMode(material_in.alphaMode); -    mat->mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); - -    mat->mBaseColor= getColor(material_in.pbrMetallicRoughness.baseColorFactor); -    mat->mEmissiveColor = getColor(material_in.emissiveFactor); - -    mat->mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f); -    mat->mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f); - -    mat->mDoubleSided = material_in.doubleSided; -} -  LLColor4 LLTinyGLTFHelper::getColor(const std::vector<double>& in)  {      LLColor4 out; diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h index afe4517417..9c2e5afc17 100644 --- a/indra/newview/lltinygltfhelper.h +++ b/indra/newview/lltinygltfhelper.h @@ -35,7 +35,6 @@ class LLViewerFetchedTexture;  namespace LLTinyGLTFHelper  { -    void setFromModel(LLGLTFMaterial* mat, tinygltf::Model& model, S32 index);      LLColor4 getColor(const std::vector<double>& in);      const tinygltf::Image* getImageFromTextureIndex(const tinygltf::Model& model, S32 texture_index);      LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name); | 
