diff options
author | Dave Parks <davep@lindenlab.com> | 2022-10-14 17:35:48 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2022-10-14 17:35:48 -0500 |
commit | f6762c3de57434730a2cbf6d0241bf1db5c9346c (patch) | |
tree | 4a112b3ce07552bc19e1c8b4474b64c292572d1f /indra/llprimitive | |
parent | a2b09df2db69ba8a2e6b587d839d509fbe5abebb (diff) |
SL-18105 Add to/from json capability to LLGLTFMaterial
Diffstat (limited to 'indra/llprimitive')
-rw-r--r-- | indra/llprimitive/CMakeLists.txt | 1 | ||||
-rw-r--r-- | indra/llprimitive/llgltfmaterial.cpp | 199 | ||||
-rw-r--r-- | indra/llprimitive/llgltfmaterial.h | 34 |
3 files changed, 229 insertions, 5 deletions
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; + +}; |