diff options
author | Ptolemy <ptolemy@lindenlab.com> | 2022-06-30 12:50:49 -0700 |
---|---|---|
committer | Ptolemy <ptolemy@lindenlab.com> | 2022-06-30 12:50:49 -0700 |
commit | 82232de0d2aecfddca2988249e79a73b4d972aa5 (patch) | |
tree | f6dfb8a8c2d0ca9ee3a3e3dca37386130ffe1653 | |
parent | 38b6f10717918643c1169a4007dc92cfe36fc4d5 (diff) | |
parent | 68dfa1f5501f58d1ca158aeabcc3fd07e8a2e70f (diff) |
Merge branch 'DRTVWR-559' of bitbucket.org:lindenlab/viewer into DRTVWR-559
-rw-r--r-- | indra/llprimitive/llgltfmaterial.h | 2 | ||||
-rw-r--r-- | indra/llprimitive/llprimitive.cpp | 109 | ||||
-rw-r--r-- | indra/llprimitive/llprimitive.h | 24 | ||||
-rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/newview/llgltfmateriallist.cpp | 186 | ||||
-rw-r--r-- | indra/newview/llgltfmateriallist.h | 48 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.cpp | 56 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.h | 4 | ||||
-rw-r--r-- | indra/newview/llpanelgroupnotices.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llpanelobjectinventory.cpp | 1 | ||||
-rw-r--r-- | indra/newview/lltooldraganddrop.cpp | 80 | ||||
-rw-r--r-- | indra/newview/lltooldraganddrop.h | 10 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 84 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 8 | ||||
-rw-r--r-- | indra/newview/llviewertexteditor.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 27 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 4 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_material_editor.xml | 3 |
19 files changed, 602 insertions, 50 deletions
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index d6f59cd1a3..a8d5fb8e85 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -53,6 +53,8 @@ public: F32 mMetallicFactor = 0.f; F32 mRoughnessFactor = 0.f; + F32 mAlphaCutoff = 0.f; + bool mDoubleSided = false; AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 9e0a079fd9..3f0059b759 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1700,7 +1700,7 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size) case PARAMS_EXTENDED_MESH: return (size == 4); case PARAMS_RENDER_MATERIAL: - return (size == 16); + return (size > 1); } return FALSE; @@ -2312,18 +2312,32 @@ LLRenderMaterialParams::LLRenderMaterialParams() mType = PARAMS_RENDER_MATERIAL; } -BOOL LLRenderMaterialParams::pack(LLDataPacker &dp) const +BOOL LLRenderMaterialParams::pack(LLDataPacker& dp) const { - return dp.packUUID(mMaterial, "material"); + U8 count = (U8)llmin((S32)mEntries.size(), 14); //limited to 255 bytes, no more than 14 material ids -// return TRUE; + dp.packU8(count, "count"); + for (auto& entry : mEntries) + { + dp.packU8(entry.te_idx, "te_idx"); + dp.packUUID(entry.id, "id"); + } + + return TRUE; } -BOOL LLRenderMaterialParams::unpack(LLDataPacker &dp) +BOOL LLRenderMaterialParams::unpack(LLDataPacker& dp) { - return dp.unpackUUID(mMaterial, "material"); + U8 count; + dp.unpackU8(count, "count"); + mEntries.resize(count); + for (auto& entry : mEntries) + { + dp.unpackU8(entry.te_idx, "te_idx"); + dp.unpackUUID(entry.id, "te_id"); + } -// return TRUE; + return TRUE; } bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const @@ -2333,40 +2347,99 @@ bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const return false; } - const LLRenderMaterialParams ¶m = static_cast<const LLRenderMaterialParams&>(data); + const LLRenderMaterialParams& param = static_cast<const LLRenderMaterialParams&>(data); + + if (param.mEntries.size() != mEntries.size()) + { + return false; + } + + for (auto& entry : mEntries) + { + if (param.getMaterial(entry.te_idx) != entry.id) + { + return false; + } + } - return param.mMaterial == mMaterial; + return true; } void LLRenderMaterialParams::copy(const LLNetworkData& data) { llassert_always(data.mType == PARAMS_RENDER_MATERIAL); - const LLRenderMaterialParams ¶m = static_cast<const LLRenderMaterialParams&>(data); - mMaterial = param.mMaterial; + const LLRenderMaterialParams& param = static_cast<const LLRenderMaterialParams&>(data); + mEntries = param.mEntries; } LLSD LLRenderMaterialParams::asLLSD() const { - return llsd::map("material", mMaterial); + LLSD ret; + + for (int i = 0; i < mEntries.size(); ++i) + { + ret[i]["te_idx"] = mEntries[i].te_idx; + ret[i]["id"] = mEntries[i].id; + } + + return ret; } bool LLRenderMaterialParams::fromLLSD(LLSD& sd) { - if (sd.has("material")) + if (sd.isArray()) { - setMaterial(sd["material"]); + mEntries.resize(sd.size()); + for (int i = 0; i < sd.size(); ++i) + { + if (sd[i].has("te_idx") && sd.has("id")) + { + mEntries[i].te_idx = sd[i]["te_idx"].asInteger(); + mEntries[i].id = sd[i]["id"].asUUID(); + } + else + { + return false; + } + } + return true; } return false; } -void LLRenderMaterialParams::setMaterial(const LLUUID & id) +void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id) { - mMaterial = id; + for (int i = 0; i < mEntries.size(); ++i) + { + if (mEntries[i].te_idx == te) + { + if (id.isNull()) + { + mEntries.erase(mEntries.begin() + i); + } + else + { + mEntries[i].id = id; + } + return; + } + } + + mEntries.push_back({ te, id }); } -LLUUID LLRenderMaterialParams::getMaterial() const +const LLUUID& LLRenderMaterialParams::getMaterial(U8 te) const { - return mMaterial; + for (int i = 0; i < mEntries.size(); ++i) + { + if (mEntries[i].te_idx == te) + { + return mEntries[i].id; + } + } + + return LLUUID::null; } + diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 25196fb894..d2adfa4a3d 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -369,22 +369,30 @@ public: class LLRenderMaterialParams : public LLNetworkData { private: - LLUUID mMaterial; + struct Entry + { + U8 te_idx; + LLUUID id; + }; + std::vector< Entry > mEntries; public: LLRenderMaterialParams(); - BOOL pack(LLDataPacker &dp) const override; - BOOL unpack(LLDataPacker &dp) override; + BOOL pack(LLDataPacker& dp) const override; + BOOL unpack(LLDataPacker& dp) override; bool operator==(const LLNetworkData& data) const override; void copy(const LLNetworkData& data) override; LLSD asLLSD() const; operator LLSD() const { return asLLSD(); } bool fromLLSD(LLSD& sd); - void setMaterial(const LLUUID & id); - LLUUID getMaterial() const; + void setMaterial(U8 te_idx, const LLUUID& id); + const LLUUID& getMaterial(U8 te_idx) const; + + bool isEmpty() { return mEntries.empty(); } }; + // This code is not naming-standards compliant. Leaving it like this for // now to make the connection to code in // BOOL packTEMessage(LLDataPacker &dp) const; @@ -480,12 +488,12 @@ public: virtual S32 setTEMediaFlags(const U8 te, const U8 flags); virtual S32 setTEGlow(const U8 te, const F32 glow); virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); - virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); + virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed virtual void setTESelected(const U8 te, bool sel); LLMaterialPtr getTEMaterialParams(const U8 index); - + void copyTEs(const LLPrimitive *primitive); S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; BOOL packTEMessage(LLMessageSystem *mesgsys) const; @@ -563,6 +571,8 @@ public: static LLPCode legacyToPCode(const U8 legacy); static U8 pCodeToLegacy(const LLPCode pcode); static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis); + + BOOL hasRenderMaterialParams() const; inline static BOOL isPrimitive(const LLPCode pcode); inline static BOOL isApp(const LLPCode pcode); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d4bd1c8b57..b67bc91277 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -344,6 +344,7 @@ set(viewer_SOURCE_FILES llgesturemgr.cpp llgiveinventory.cpp llglsandbox.cpp + llgltfmateriallist.cpp llgroupactions.cpp llgroupiconctrl.cpp llgrouplist.cpp @@ -986,6 +987,7 @@ set(viewer_HEADER_FILES llgesturelistener.h llgesturemgr.h llgiveinventory.h + llgltfmateriallist.h llgroupactions.h llgroupiconctrl.h llgrouplist.h diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp new file mode 100644 index 0000000000..7ecbc6eeac --- /dev/null +++ b/indra/newview/llgltfmateriallist.cpp @@ -0,0 +1,186 @@ +/** + * @file llgltfmateriallist.cpp + * + * $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 "llviewerprecompiledheaders.h" + +#include "llgltfmateriallist.h" + +#include "llassetstorage.h" +#include "llfilesystem.h" +#include "llsdserialize.h" + +#include "tinygltf/tiny_gltf.h" +#include <strstream> + +LLGLTFMaterialList gGLTFMaterialList; + +static LLColor4 get_color(const std::vector<double>& in) +{ + LLColor4 out; + for (S32 i = 0; i < llmin((S32)in.size(), 4); ++i) + { + out.mV[i] = in[i]; + } + + return out; +} + +static void set_from_model(LLGLTFMaterial* mat, tinygltf::Model& model) +{ + + S32 index; + + auto& material_in = model.materials[0]; + + // get albedo texture + index = material_in.pbrMetallicRoughness.baseColorTexture.index; + if (index >= 0) + { + mat->mAlbedoId.set(model.images[index].uri); + } + else + { + mat->mAlbedoId.setNull(); + } + + // get normal map + index = material_in.normalTexture.index; + if (index >= 0) + { + mat->mNormalId.set(model.images[index].uri); + } + else + { + mat->mNormalId.setNull(); + } + + // get metallic-roughness texture + index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; + if (index >= 0) + { + mat->mMetallicRoughnessId.set(model.images[index].uri); + } + else + { + mat->mMetallicRoughnessId.setNull(); + } + + // get emissive texture + index = material_in.emissiveTexture.index; + if (index >= 0) + { + mat->mEmissiveId.set(model.images[index].uri); + } + else + { + mat->mEmissiveId.setNull(); + } + + mat->setAlphaMode(material_in.alphaMode); + mat->mAlphaCutoff = material_in.alphaCutoff; + + mat->mAlbedoColor = get_color(material_in.pbrMetallicRoughness.baseColorFactor); + mat->mEmissiveColor = get_color(material_in.emissiveFactor); + + mat->mMetallicFactor = material_in.pbrMetallicRoughness.metallicFactor; + mat->mRoughnessFactor = material_in.pbrMetallicRoughness.roughnessFactor; + + mat->mDoubleSided = material_in.doubleSided; +} + +LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) +{ + List::iterator iter = mList.find(id); + if (iter == mList.end()) + { + LLGLTFMaterial* mat = new LLGLTFMaterial(); + mList[id] = mat; + + mat->ref(); + + gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, + [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status) + { + if (status) + { + LL_WARNS() << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL; + } + + LLFileSystem file(id, asset_type, LLFileSystem::READ); + + std::vector<char> buffer; + buffer.resize(file.getSize()); + file.read((U8*)&buffer[0], buffer.size()); + + LLSD asset; + + // read file into buffer + std::istrstream str(&buffer[0], buffer.size()); + + if (LLSDSerialize::deserialize(asset, str, buffer.size())) + { + if (asset.has("version") && asset["version"] == "1.0") + { + if (asset.has("type") && asset["type"].asString() == "GLTF 2.0") + { + if (asset.has("data") && asset["data"].isString()) + { + std::string data = asset["data"]; + + tinygltf::TinyGLTF gltf; + tinygltf::TinyGLTF loader; + std::string error_msg; + std::string warn_msg; + + tinygltf::Model model_in; + + if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), "")) + { + set_from_model(mat, model_in); + } + else + { + LL_WARNS() << "Failed to decode material asset: " << LL_ENDL; + LL_WARNS() << warn_msg << LL_ENDL; + LL_WARNS() << error_msg << LL_ENDL; + } + } + } + } + } + else + { + LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL; + } + + mat->unref(); + }, nullptr); + + return mat; + } + + return iter->second; +} + diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h new file mode 100644 index 0000000000..c22134c468 --- /dev/null +++ b/indra/newview/llgltfmateriallist.h @@ -0,0 +1,48 @@ +/** + * @file llgltfmateriallist.h + * + * $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$ + */ + + +#pragma once + +#include "llgltfmaterial.h" +#include "llpointer.h" + +#include <unordered_map> + +class LLGLTFMaterialList +{ +public: + LLGLTFMaterialList() {} + + typedef std::unordered_map<LLUUID, LLPointer<LLGLTFMaterial > > List; + List mList; + + LLGLTFMaterial* getMaterial(const LLUUID& id); + +}; + +extern LLGLTFMaterialList gGLTFMaterialList; + + diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 2bb2c9676b..d325831c8f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4403,6 +4403,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_GESTURE: case DAD_MESH: case DAD_SETTINGS: + case DAD_MATERIAL: accept = dragItemIntoFolder(inv_item, drop, tooltip_msg); break; case DAD_LINK: @@ -6032,6 +6033,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_GESTURE: case DAD_MESH: case DAD_SETTINGS: + case DAD_MATERIAL: { LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data; const LLPermissions& perm = inv_item->getPermissions(); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 2455ad2926..67d963bb63 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -29,6 +29,7 @@ #include "llmaterialeditor.h" #include "llagent.h" +#include "llagentbenefits.h" #include "llappviewer.h" #include "llcombobox.h" #include "llinventorymodel.h" @@ -43,7 +44,6 @@ #include "llviewerregion.h" #include "llvovolume.h" #include "roles_constants.h" -#include "tinygltf/tiny_gltf.h" #include "llviewerobjectlist.h" #include "llfloaterreg.h" #include "llfilesystem.h" @@ -52,6 +52,7 @@ #include "llviewertexturelist.h" #include "llfloaterperms.h" +#include "tinygltf/tiny_gltf.h" #include <strstream> ///---------------------------------------------------------------------------- @@ -86,6 +87,12 @@ BOOL LLMaterialEditor::postBuild() childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); + S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); + getChild<LLUICtrl>("albedo_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void*) { setHasUnsavedChanges(true); @@ -142,7 +149,12 @@ void LLMaterialEditor::setAlbedoId(const LLUUID& id) { mAlbedoTextureCtrl->setValue(id); mAlbedoTextureCtrl->setDefaultImageAssetID(id); +} +void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id) +{ + // Might be better to use local textures and + // assign a fee in case of a local texture if (id.notNull()) { // todo: this does not account for posibility of texture @@ -151,6 +163,7 @@ void LLMaterialEditor::setAlbedoId(const LLUUID& id) // Only set if we will need to upload this texture mAlbedoTextureUploadId = id; } + setHasUnsavedChanges(true); } LLColor4 LLMaterialEditor::getAlbedoColor() @@ -211,7 +224,10 @@ void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id) { mMetallicTextureCtrl->setValue(id); mMetallicTextureCtrl->setDefaultImageAssetID(id); +} +void LLMaterialEditor::setMetallicRoughnessUploadId(const LLUUID& id) +{ if (id.notNull()) { // todo: this does not account for posibility of texture @@ -219,6 +235,7 @@ void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id) childSetValue("metallic_upload_fee", getString("upload_fee_string")); mMetallicTextureUploadId = id; } + setHasUnsavedChanges(true); } F32 LLMaterialEditor::getMetalnessFactor() @@ -250,7 +267,10 @@ void LLMaterialEditor::setEmissiveId(const LLUUID& id) { mEmissiveTextureCtrl->setValue(id); mEmissiveTextureCtrl->setDefaultImageAssetID(id); +} +void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id) +{ if (id.notNull()) { // todo: this does not account for posibility of texture @@ -258,6 +278,7 @@ void LLMaterialEditor::setEmissiveId(const LLUUID& id) childSetValue("emissive_upload_fee", getString("upload_fee_string")); mEmissiveTextureUploadId = id; } + setHasUnsavedChanges(true); } LLColor4 LLMaterialEditor::getEmissiveColor() @@ -279,7 +300,10 @@ void LLMaterialEditor::setNormalId(const LLUUID& id) { mNormalTextureCtrl->setValue(id); mNormalTextureCtrl->setDefaultImageAssetID(id); +} +void LLMaterialEditor::setNormalUploadId(const LLUUID& id) +{ if (id.notNull()) { // todo: this does not account for posibility of texture @@ -287,6 +311,7 @@ void LLMaterialEditor::setNormalId(const LLUUID& id) childSetValue("normal_upload_fee", getString("upload_fee_string")); mNormalTextureUploadId = id; } + setHasUnsavedChanges(true); } bool LLMaterialEditor::getDoubleSided() @@ -306,6 +331,27 @@ void LLMaterialEditor::setHasUnsavedChanges(bool value) mHasUnsavedChanges = value; childSetVisible("unsaved_changes", value); } + + S32 upload_texture_count = 0; + if (mAlbedoTextureUploadId.notNull() && mAlbedoTextureUploadId == getAlbedoId()) + { + upload_texture_count++; + } + if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId()) + { + upload_texture_count++; + } + if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId()) + { + upload_texture_count++; + } + if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId()) + { + upload_texture_count++; + } + + S32 upload_cost = upload_texture_count * LLAgentBenefitsMgr::current().getTextureUploadCost(); + getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); } void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) @@ -866,6 +912,8 @@ static void pack_textures(tinygltf::Model& model, tinygltf::Material& material, LLPointer<LLImageJ2C>& mr_j2c, LLPointer<LLImageJ2C>& emissive_j2c) { + // todo: consider using LLLocalBitmapMgr or storing textures' pointers somewhere in floater + // otherwise images won't exist for long if texture ctrl temporaly switches to something else if (albedo_img) { albedo_tex = LLViewerTextureManager::getFetchedTexture(albedo_img, FTType::FTT_LOCAL_FILE, true); @@ -1035,9 +1083,13 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) } mME->setAlbedoId(albedo_id); + mME->setAlbedoUploadId(albedo_id); mME->setMetallicRoughnessId(mr_id); + mME->setMetallicRoughnessUploadId(mr_id); mME->setEmissiveId(emissive_id); + mME->setEmissiveUploadId(emissive_id); mME->setNormalId(normal_id); + mME->setNormalUploadId(normal_id); mME->setFromGltfModel(model_in); @@ -1383,7 +1435,7 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con std::string buffer; buffer.assign((const char*) img->getData(), img->getDataSize()); - U32 expected_upload_cost = 10; // TODO: where do we get L$10 for textures from? + U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); LLAssetStorage::LLStoreAssetCallback callback; diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 6ccb27cf27..b2a6e96eac 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -99,6 +99,7 @@ public: LLUUID getAlbedoId(); void setAlbedoId(const LLUUID& id); + void setAlbedoUploadId(const LLUUID& id); LLColor4 getAlbedoColor(); @@ -118,6 +119,7 @@ public: LLUUID getMetallicRoughnessId(); void setMetallicRoughnessId(const LLUUID& id); + void setMetallicRoughnessUploadId(const LLUUID& id); F32 getMetalnessFactor(); void setMetalnessFactor(F32 factor); @@ -127,12 +129,14 @@ public: LLUUID getEmissiveId(); void setEmissiveId(const LLUUID& id); + void setEmissiveUploadId(const LLUUID& id); LLColor4 getEmissiveColor(); void setEmissiveColor(const LLColor4& color); LLUUID getNormalId(); void setNormalId(const LLUUID& id); + void setNormalUploadId(const LLUUID& id); bool getDoubleSided(); void setDoubleSided(bool double_sided); diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index ab32ea3956..82f880c9ee 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -156,6 +156,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, case DAD_CALLINGCARD: case DAD_MESH: case DAD_SETTINGS: + case DAD_MATERIAL: { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index defd7025b8..998cffef4a 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -704,6 +704,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_CALLINGCARD: case DAD_MESH: case DAD_SETTINGS: + case DAD_MATERIAL: accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); if(accept && drop) { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 50868d0fa5..55e8a3b98b 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -256,7 +256,8 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() // |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------| addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_MATERIAL, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMaterialObject, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL)); @@ -271,6 +272,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_SETTINGS, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + // TODO: animation on self could play it? edit it? // TODO: gesture on self could play it? edit it? }; @@ -1062,6 +1064,64 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, hit_obj->sendTEUpdate(); } + +void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj, + S32 hit_face, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id) +{ + if (hit_face == -1) return; + if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL) + { + LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL; + return; + } + LLUUID asset_id = item->getAssetUUID(); + BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id); + if (!success) + { + return; + } + + hit_obj->setRenderMaterialID(hit_face, asset_id); + + dialog_refresh_all(); + + // send the update to the simulator + hit_obj->sendTEUpdate(); +} + + +void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id) +{ + if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL) + { + LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL; + return; + } + LLUUID asset_id = item->getAssetUUID(); + BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id); + if (!success) + { + return; + } + + S32 num_faces = hit_obj->getNumTEs(); + for (S32 face = 0; face < num_faces; face++) + { + // update viewer side material in anticipation of update from simulator + hit_obj->setRenderMaterialID(face, asset_id); + dialog_refresh_all(); + } + // send the update to the simulator + hit_obj->sendTEUpdate(); +} + + void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj, LLInventoryItem* item, LLToolDragAndDrop::ESource source, @@ -1628,6 +1688,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ case DAD_MESH: case DAD_CATEGORY: case DAD_SETTINGS: + case DAD_MATERIAL: { LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data; if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID()) @@ -1982,6 +2043,17 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( dropTextureOneFace(obj, face, item, mSource, mSourceID); } } + else if (cargo_type == DAD_MATERIAL) + { + if ((mask & MASK_SHIFT)) + { + dropMaterialAllFaces(obj, item, mSource, mSourceID); + } + else + { + dropMaterialOneFace(obj, face, item, mSource, mSourceID); + } + } else if (cargo_type == DAD_MESH) { dropMesh(obj, item, mSource, mSourceID); @@ -2010,6 +2082,12 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject( return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE); } +EAcceptance LLToolDragAndDrop::dad3dMaterialObject( + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + return dad3dApplyToObject(obj, face, mask, drop, DAD_MATERIAL); +} + EAcceptance LLToolDragAndDrop::dad3dMeshObject( LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 24a712029c..2f6423080e 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -168,6 +168,8 @@ protected: MASK mask, BOOL drop); EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face, MASK mask, BOOL drop); + EAcceptance dad3dMaterialObject(LLViewerObject* obj, S32 face, + MASK mask, BOOL drop); EAcceptance dad3dMeshObject(LLViewerObject* obj, S32 face, MASK mask, BOOL drop); // EAcceptance dad3dTextureSelf(LLViewerObject* obj, S32 face, @@ -249,6 +251,14 @@ public: LLInventoryItem* item, ESource source, const LLUUID& src_id); + static void dropMaterialOneFace(LLViewerObject* hit_obj, S32 hit_face, + LLInventoryItem* item, + ESource source, + const LLUUID& src_id); + static void dropMaterialAllFaces(LLViewerObject* hit_obj, + LLInventoryItem* item, + ESource source, + const LLUUID& src_id); static void dropMesh(LLViewerObject* hit_obj, LLInventoryItem* item, ESource source, diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 16479e02a2..753fb014c9 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -107,6 +107,7 @@ #include "llcleanup.h" #include "llcallstack.h" #include "llmeshrepository.h" +#include "llgltfmateriallist.h" #include "llgl.h" //#define DEBUG_UPDATE_TYPE @@ -4906,6 +4907,18 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) }; LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial(); + LLUUID mat_id = getRenderMaterialID(te); + if (mat == nullptr && mat_id.notNull()) + { + mat = gGLTFMaterialList.getMaterial(mat_id); + getTE(te)->setGLTFMaterial(mat); + } + else if (mat_id.isNull() && mat != nullptr) + { + mat = nullptr; + getTE(te)->setGLTFMaterial(nullptr); + } + if (mat != nullptr) { mGLTFAlbedoMaps[te] = fetch_texture(mat->mAlbedoId); @@ -4913,6 +4926,14 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId); mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId); } + else + { + mGLTFAlbedoMaps[te] = nullptr; + mGLTFNormalMaps[te] = nullptr; + mGLTFMetallicRoughnessMaps[te] = nullptr; + mGLTFEmissiveMaps[te] = nullptr; + } + } void LLViewerObject::refreshBakeTexture() @@ -6991,6 +7012,69 @@ LLVOAvatar* LLViewerObject::getAvatar() const return NULL; } +bool LLViewerObject::hasRenderMaterialParams() const +{ + return getParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL); +} + +void LLViewerObject::setHasRenderMaterialParams(bool has_materials) +{ + bool had_materials = hasRenderMaterialParams(); + + if (had_materials != has_materials) + { + if (has_materials) + { + setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, true); + } + else + { + setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, FALSE, true); + } + } +} + +const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const +{ + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + return param_block->getMaterial(te); + } + + return LLUUID::null; +} + +void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id) +{ + if (id.notNull()) + { + getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id)); + setHasRenderMaterialParams(true); + } + else + { + getTE(te)->setGLTFMaterial(nullptr); + } + + faceMappingChanged(); + gPipeline.markTextured(mDrawable); + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + param_block->setMaterial(te, id); + + if (param_block->isEmpty()) + { // might be empty if id is null + setHasRenderMaterialParams(false); + } + else + { + parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); + } + } +} class ObjectPhysicsProperties : public LLHTTPNode { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 5136a7e5ee..109c96dc9c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -179,6 +179,13 @@ public: const std::string& getAttachmentItemName() const; virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment + + bool hasRenderMaterialParams() const; + void setHasRenderMaterialParams(bool has_params); + + const LLUUID& getRenderMaterialID(U8 te) const; + void setRenderMaterialID(U8 te, const LLUUID& id); + virtual BOOL isHUDAttachment() const { return FALSE; } virtual BOOL isTempAttachment() const; @@ -200,6 +207,7 @@ public: // Graphical stuff for objects - maybe broken out into render class later? virtual void updateTextures(); + virtual void faceMappingChanged() {} virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object virtual LLDrawable* createDrawable(LLPipeline *pipeline); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index e2de7ac825..7c860936a5 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -879,6 +879,7 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, case DAD_ANIMATION: case DAD_GESTURE: case DAD_MESH: + case DAD_MATERIAL: { supported = true; break; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0ae13e67cd..4fa9f05c09 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2161,6 +2161,7 @@ void LLVOVolume::setNumTEs(const U8 num_tes) return ; } + //virtual void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep) { @@ -3500,6 +3501,11 @@ F32 LLVOVolume::getLightCutoff() const } } +BOOL LLVOVolume::isReflectionProbe() const +{ + return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); +} + void LLVOVolume::setIsReflectionProbe(BOOL is_probe) { BOOL was_probe = isReflectionProbe(); @@ -3570,25 +3576,6 @@ void LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic) } } - -BOOL LLVOVolume::isReflectionProbe() const -{ - // HACK - make this object a Reflection Probe if a certain UUID is detected - static LLCachedControl<std::string> reflection_probe_id(gSavedSettings, "RenderReflectionProbeTextureHackID", ""); - LLUUID probe_id(reflection_probe_id); - - for (U8 i = 0; i < getNumTEs(); ++i) - { - if (getTE(i)->getID() == probe_id) - { - return true; - } - } - // END HACK - - return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); -} - F32 LLVOVolume::getReflectionProbeAmbiance() const { const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); @@ -5874,6 +5861,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } + // HACK -- brute force this check every time a drawable gets rebuilt + vobj->updateTEMaterialTextures(i); #if 0 #if LL_RELEASE_WITH_DEBUG_INFO const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" ); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index f0a4fd427e..db586fd741 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -172,7 +172,7 @@ public: void markForUpdate(BOOL priority) override; void markForUnload() { LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; } - void faceMappingChanged() { mFaceMappingChanged=TRUE; }; + void faceMappingChanged() override { mFaceMappingChanged=TRUE; } /*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts @@ -284,7 +284,7 @@ public: F32 getLightRadius() const; F32 getLightFalloff(const F32 fudge_factor = 1.f) const; F32 getLightCutoff() const; - + // Reflection Probes void setIsReflectionProbe(BOOL is_probe); void setReflectionProbeAmbiance(F32 ambiance); diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml index df06896fa5..7d532ecd7b 100644 --- a/indra/newview/skins/default/xui/en/floater_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml @@ -10,7 +10,7 @@ title="[MATERIAL_NAME]" width="256"> <string name="no_upload_fee_string">no upload fee</string> - <string name="upload_fee_string">L$10 upload fee</string> + <string name="upload_fee_string">L$[FEE] upload fee</string> <check_box follows="left|top" label="Double Sided" @@ -473,6 +473,7 @@ layout="topleft" left="10" top_pad="5" + name="total_upload_fee" > Total upload fee: L$ [FEE] </text> |