diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-11-04 18:57:48 +0200 |
---|---|---|
committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-11-04 18:57:48 +0200 |
commit | 11c87378be68d9102d7dcf94d714b3c5c1923952 (patch) | |
tree | d7a3cd05c69172c328233166c2ad0c0b6fc9b555 | |
parent | d26f545c5aa22d8267a2284c787bc9503e8b6cc9 (diff) |
SL-18560 Make local materials save correctly from right-click menu
-rw-r--r-- | indra/newview/lllocalgltfmaterials.cpp | 46 | ||||
-rw-r--r-- | indra/newview/lllocalgltfmaterials.h | 21 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.cpp | 150 | ||||
-rw-r--r-- | indra/newview/lltinygltfhelper.cpp | 13 | ||||
-rw-r--r-- | indra/newview/lltinygltfhelper.h | 6 |
5 files changed, 133 insertions, 103 deletions
diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index 03ef12bde1..b07efff827 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -61,7 +61,6 @@ static const S32 LL_LOCAL_UPDATE_RETRIES = 5; LLLocalGLTFMaterial::LLLocalGLTFMaterial(std::string filename, S32 index) : mFilename(filename) , mShortName(gDirUtilp->getBaseFileName(filename, true)) - , mValid(false) , mLastModified() , mLinkStatus(LS_ON) , mUpdateRetries(LL_LOCAL_UPDATE_RETRIES) @@ -86,17 +85,11 @@ LLLocalGLTFMaterial::LLLocalGLTFMaterial(std::string filename, S32 index) << "Filename: " << mFilename << LL_ENDL; return; // no valid extension. } - - /* next phase of unit creation is nearly the same as an update cycle. - we're running updateSelf as a special case with the optional UT_FIRSTUSE - which omits the parts associated with removing the outdated texture */ - mValid = updateSelf(); } LLLocalGLTFMaterial::~LLLocalGLTFMaterial() { - // delete self from material list - gGLTFMaterialList.removeMaterial(mWorldID); + // gGLTFMaterialList will clean itself } /* accessors */ @@ -125,11 +118,6 @@ S32 LLLocalGLTFMaterial::getIndexInFile() return mMaterialIndex; } -bool LLLocalGLTFMaterial::getValid() -{ - return mValid; -} - /* update functions */ bool LLLocalGLTFMaterial::updateSelf() { @@ -163,7 +151,7 @@ bool LLLocalGLTFMaterial::updateSelf() // addMaterial will replace material witha a new // pointer if value already exists but we are // reusing existing pointer, so it should add only. - gGLTFMaterialList.addMaterial(mWorldID, mGLTFMaterial); + gGLTFMaterialList.addMaterial(mWorldID, this); mUpdateRetries = LL_LOCAL_UPDATE_RETRIES; updated = true; @@ -217,17 +205,6 @@ bool LLLocalGLTFMaterial::loadMaterial() { bool decode_successful = false; - if (mWorldID.notNull()) - { - // We should already have it, but update mGLTFMaterial just in case - // will create a new one if material doesn't exist yet - mGLTFMaterial = (LLFetchedGLTFMaterial*)gGLTFMaterialList.getMaterial(mWorldID); - } - else - { - mGLTFMaterial = new LLFetchedGLTFMaterial(); - } - switch (mExtension) { case ET_MATERIAL_GLTF: @@ -241,12 +218,8 @@ bool LLLocalGLTFMaterial::loadMaterial() decode_successful = LLTinyGLTFHelper::getMaterialFromFile( mFilename, mMaterialIndex, - mGLTFMaterial, - material_name, - mBaseColorFetched, - mNormalFetched, - mMRFetched, - mEmissiveFetched); + this, + material_name); if (!material_name.empty()) { @@ -315,7 +288,6 @@ LLLocalGLTFMaterialMgr::LLLocalGLTFMaterialMgr() LLLocalGLTFMaterialMgr::~LLLocalGLTFMaterialMgr() { - std::for_each(mMaterialList.begin(), mMaterialList.end(), DeletePointer()); mMaterialList.clear(); } @@ -386,11 +358,12 @@ S32 LLLocalGLTFMaterialMgr::addUnit(const std::string& filename) // Todo: this is rather inefficient, files will be spammed with // separate loads and date checks, find a way to improve this. // May be doUpdates() should be checking individual files. - LLLocalGLTFMaterial* unit = new LLLocalGLTFMaterial(filename, i); + LLPointer<LLLocalGLTFMaterial> unit = new LLLocalGLTFMaterial(filename, i); - if (unit->getValid()) + // load material from file + if (unit->updateSelf()) { - mMaterialList.push_back(unit); + mMaterialList.emplace_back(unit); loaded_materials++; } else @@ -402,7 +375,6 @@ S32 LLLocalGLTFMaterialMgr::addUnit(const std::string& filename) notif_args["FNAME"] = filename; LLNotificationsUtil::add("LocalGLTFVerifyFail", notif_args); - delete unit; unit = NULL; } } @@ -429,7 +401,7 @@ void LLLocalGLTFMaterialMgr::delUnit(LLUUID tracking_id) { /* iterating over a temporary list, hence preserving the iterator validity while deleting. */ LLLocalGLTFMaterial* unit = *del_iter; mMaterialList.remove(unit); - delete unit; + unit = NULL; } } diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h index 097f2ea30a..3bdccbbf3d 100644 --- a/indra/newview/lllocalgltfmaterials.h +++ b/indra/newview/lllocalgltfmaterials.h @@ -29,18 +29,17 @@ #include "lleventtimer.h" #include "llpointer.h" +#include "llgltfmateriallist.h" class LLScrollListCtrl; class LLGLTFMaterial; class LLViewerObject; -class LLViewerFetchedTexture; -class LLFetchedGLTFMaterial; -class LLLocalGLTFMaterial +class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial { public: /* main */ LLLocalGLTFMaterial(std::string filename, S32 index); - ~LLLocalGLTFMaterial(); + virtual ~LLLocalGLTFMaterial(); public: /* accessors */ std::string getFilename(); @@ -48,7 +47,6 @@ public: /* accessors */ LLUUID getTrackingID(); LLUUID getWorldID(); S32 getIndexInFile(); - bool getValid(); public: bool updateSelf(); @@ -74,20 +72,11 @@ private: /* members */ std::string mShortName; LLUUID mTrackingID; LLUUID mWorldID; - bool mValid; LLSD mLastModified; EExtension mExtension; ELinkStatus mLinkStatus; S32 mUpdateRetries; S32 mMaterialIndex; // Single file can have more than one - - // Maintain textures and material pointers to - // make sure they won't be deleted in any way - LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial; - LLPointer<LLViewerFetchedTexture> mBaseColorFetched; - LLPointer<LLViewerFetchedTexture> mNormalFetched; - LLPointer<LLViewerFetchedTexture> mMRFetched; - LLPointer<LLViewerFetchedTexture> mEmissiveFetched; }; class LLLocalGLTFMaterialTimer : public LLEventTimer @@ -120,9 +109,9 @@ public: void doUpdates(); private: - std::list<LLLocalGLTFMaterial*> mMaterialList; + std::list<LLPointer<LLLocalGLTFMaterial> > mMaterialList; LLLocalGLTFMaterialTimer mTimer; - typedef std::list<LLLocalGLTFMaterial*>::iterator local_list_iter; + typedef std::list<LLPointer<LLLocalGLTFMaterial> >::iterator local_list_iter; }; #endif // LL_LOCALGLTFMATERIALS_H diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 397a302069..9173981c01 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -36,6 +36,7 @@ #include "llfilesystem.h" #include "llgltfmateriallist.h" #include "llinventorymodel.h" +#include "lllocalgltfmaterials.h" #include "llnotificationsutil.h" #include "lltexturectrl.h" #include "lltrans.h" @@ -236,6 +237,7 @@ struct LLSelectedTEGetMatData : public LLSelectedTEFunctor LLUUID mObjectId; S32 mObjectTE; LLPointer<LLGLTFMaterial> mMaterial; + LLPointer<LLLocalGLTFMaterial> mLocalMaterial; }; LLSelectedTEGetMatData::LLSelectedTEGetMatData(bool for_override) @@ -262,48 +264,63 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) // or has no base material if (can_use && tep && mat_id.notNull()) { - LLPointer<LLGLTFMaterial> mat = tep->getGLTFRenderMaterial(); - LLUUID tex_color_id; - LLUUID tex_metal_id; - LLUUID tex_emissive_id; - LLUUID tex_normal_id; - llassert(mat.notNull()); // by this point shouldn't be null - if (mat.notNull()) - { - tex_color_id = mat->mBaseColorId; - tex_metal_id = mat->mMetallicRoughnessId; - tex_emissive_id = mat->mEmissiveId; - tex_normal_id = mat->mNormalId; - } - if (mFirst) - { - mMaterial = mat; - mTexColorId = tex_color_id; - mTexMetalId = tex_metal_id; - mTexEmissiveId = tex_emissive_id; - mTexNormalId = tex_normal_id; - mObjectTE = te_index; - mObjectId = objectp->getID(); - mFirst = false; - } - else + if (mIsOverride) { - if (mTexColorId != tex_color_id) + LLPointer<LLGLTFMaterial> mat = tep->getGLTFRenderMaterial(); + + LLUUID tex_color_id; + LLUUID tex_metal_id; + LLUUID tex_emissive_id; + LLUUID tex_normal_id; + llassert(mat.notNull()); // by this point shouldn't be null + if (mat.notNull()) { - mIdenticalTexColor = false; + tex_color_id = mat->mBaseColorId; + tex_metal_id = mat->mMetallicRoughnessId; + tex_emissive_id = mat->mEmissiveId; + tex_normal_id = mat->mNormalId; } - if (mTexMetalId != tex_metal_id) + if (mFirst) { - mIdenticalTexMetal = false; + mMaterial = mat; + mTexColorId = tex_color_id; + mTexMetalId = tex_metal_id; + mTexEmissiveId = tex_emissive_id; + mTexNormalId = tex_normal_id; + mObjectTE = te_index; + mObjectId = objectp->getID(); + mFirst = false; } - if (mTexEmissiveId != tex_emissive_id) + else { - mIdenticalTexEmissive = false; + if (mTexColorId != tex_color_id) + { + mIdenticalTexColor = false; + } + if (mTexMetalId != tex_metal_id) + { + mIdenticalTexMetal = false; + } + if (mTexEmissiveId != tex_emissive_id) + { + mIdenticalTexEmissive = false; + } + if (mTexNormalId != tex_normal_id) + { + mIdenticalTexNormal = false; + } } - if (mTexNormalId != tex_normal_id) + } + else + { + LLGLTFMaterial *mat = tep->getGLTFMaterial(); + LLLocalGLTFMaterial *local_mat = dynamic_cast<LLLocalGLTFMaterial*>(mat); + + if (local_mat) { - mIdenticalTexNormal = false; + mLocalMaterial = local_mat; } + mMaterial = tep->getGLTFRenderMaterial(); } } return true; @@ -349,7 +366,7 @@ void LLMaterialEditor::setAuxItem(const LLInventoryItem* item) BOOL LLMaterialEditor::postBuild() { // if this is a 'live editor' instance, it is also - // single instacne and uses live overrides + // single instance and uses live overrides mIsOverride = getIsSingleInstance(); mBaseColorTextureCtrl = getChild<LLTextureCtrl>("base_color_texture"); @@ -1691,17 +1708,69 @@ void LLMaterialEditor::loadLive() void LLMaterialEditor::saveObjectsMaterialAs() { - LLSD args; - args["DESC"] = LLTrans::getString("New Material"); - - LLSD payload; // Find an applicable material. // Do this before showing message, because // message is going to drop selection. LLSelectedTEGetMatData func(false); - LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); + if (func.mLocalMaterial.notNull()) + { + // This is a local material, reload it from file + // so that user won't end up with grey textures + // on next login. + LLMaterialEditor::loadMaterialFromFile(func.mLocalMaterial->getFilename(), func.mLocalMaterial->getIndexInFile()); + + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); + if (me) + { + // apply differences on top + LLGLTFMaterial* local_mat = func.mLocalMaterial.get(); + // don't use override mat here, it has 'hacked ids' + // and values, use end result. + LLGLTFMaterial* cmp_mat = func.mMaterial.get(); + + me->setBaseColor(cmp_mat->mBaseColor); + me->setMetalnessFactor(cmp_mat->mMetallicFactor); + me->setRoughnessFactor(cmp_mat->mRoughnessFactor); + me->setEmissiveColor(cmp_mat->mEmissiveColor); + me->setDoubleSided(cmp_mat->mDoubleSided); + me->setAlphaMode(cmp_mat->getAlphaMode()); + me->setAlphaCutoff(cmp_mat->mAlphaCutoff); + + // most things like colors we can apply without verifying + // but texture ids are going to be different from both, base and override + // so only apply override id if there is actually a difference + if (local_mat->mBaseColorId != cmp_mat->mBaseColorId) + { + me->setBaseColorId(cmp_mat->mBaseColorId); + me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string")); + } + if (local_mat->mNormalId != cmp_mat->mNormalId) + { + me->setNormalId(cmp_mat->mNormalId); + me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string")); + } + if (local_mat->mMetallicRoughnessId != cmp_mat->mMetallicRoughnessId) + { + me->setMetallicRoughnessId(cmp_mat->mMetallicRoughnessId); + me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string")); + } + if (local_mat->mEmissiveId != cmp_mat->mEmissiveId) + { + me->setEmissiveId(cmp_mat->mEmissiveId); + me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string")); + } + + // recalculate upload prices + me->markChangesUnsaved(0); + } + + return; + } + + LLSD payload; if (func.mMaterial.notNull()) { payload["data"] = func.mMaterial->asJSON(); @@ -1715,6 +1784,9 @@ void LLMaterialEditor::saveObjectsMaterialAs() LL_WARNS() << "Got no material when trying to save material" << LL_ENDL; } + LLSD args; + args["DESC"] = LLTrans::getString("New Material"); + LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2)); } diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index cff26ea51f..58031d4204 100644 --- a/indra/newview/lltinygltfhelper.cpp +++ b/indra/newview/lltinygltfhelper.cpp @@ -186,11 +186,7 @@ bool LLTinyGLTFHelper::getMaterialFromFile( const std::string& filename, S32 mat_index, LLPointer < LLFetchedGLTFMaterial> material, - std::string& material_name, - LLPointer<LLViewerFetchedTexture>& base_color_tex, - LLPointer<LLViewerFetchedTexture>& normal_tex, - LLPointer<LLViewerFetchedTexture>& mr_tex, - LLPointer<LLViewerFetchedTexture>& emissive_tex) + std::string& material_name) { tinygltf::TinyGLTF loader; std::string error_msg; @@ -249,6 +245,11 @@ bool LLTinyGLTFHelper::getMaterialFromFile( occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index); } + LLPointer<LLViewerFetchedTexture> base_color_tex; + LLPointer<LLViewerFetchedTexture> normal_tex; + LLPointer<LLViewerFetchedTexture> mr_tex; + LLPointer<LLViewerFetchedTexture> emissive_tex; + // todo: pass it into local bitmaps? LLTinyGLTFHelper::initFetchedTextures(material_in, base_img, normal_img, mr_img, emissive_img, occlusion_img, @@ -258,7 +259,7 @@ bool LLTinyGLTFHelper::getMaterialFromFile( { base_color_tex->addTextureStats(64.f * 64.f, TRUE); material->mBaseColorId = base_color_tex->getID(); - material->mBaseColorTexture = base_color_tex; + material->mBaseColorTexture; } else { diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h index 48a6985641..250a4b0b9a 100644 --- a/indra/newview/lltinygltfhelper.h +++ b/indra/newview/lltinygltfhelper.h @@ -47,11 +47,7 @@ namespace LLTinyGLTFHelper const std::string& filename, S32 mat_index, LLPointer < LLFetchedGLTFMaterial> material, - std::string& material_name, - LLPointer<LLViewerFetchedTexture>& base_color_tex, - LLPointer<LLViewerFetchedTexture>& normal_tex, - LLPointer<LLViewerFetchedTexture>& mr_tex, - LLPointer<LLViewerFetchedTexture>& emissive_tex); + std::string& material_name); void initFetchedTextures(tinygltf::Material& material, LLPointer<LLImageRaw>& base_color_img, |