diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/lllocalgltfmaterials.cpp | 48 | ||||
-rw-r--r-- | indra/newview/lllocalgltfmaterials.h | 21 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.cpp | 461 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.h | 16 | ||||
-rw-r--r-- | indra/newview/llpanelface.cpp | 16 | ||||
-rw-r--r-- | indra/newview/llselectmgr.cpp | 100 | ||||
-rw-r--r-- | indra/newview/llselectmgr.h | 16 | ||||
-rw-r--r-- | indra/newview/lltinygltfhelper.cpp | 11 | ||||
-rw-r--r-- | indra/newview/lltinygltfhelper.h | 6 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 31 |
10 files changed, 517 insertions, 209 deletions
diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index 3912ed5e30..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: @@ -238,15 +215,11 @@ bool LLLocalGLTFMaterial::loadMaterial() std::string material_name; // Might be a good idea to make these textures into local textures - LLTinyGLTFHelper::getMaterialFromFile( + 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 749b5a4c1b..a0cb4e1c8f 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -31,11 +31,13 @@ #include "llagent.h" #include "llagentbenefits.h" #include "llappviewer.h" +#include "llcolorswatch.h" #include "llcombobox.h" #include "llfloaterreg.h" #include "llfilesystem.h" #include "llgltfmateriallist.h" #include "llinventorymodel.h" +#include "lllocalgltfmaterials.h" #include "llnotificationsutil.h" #include "lltexturectrl.h" #include "lltrans.h" @@ -236,6 +238,7 @@ struct LLSelectedTEGetMatData : public LLSelectedTEFunctor LLUUID mObjectId; S32 mObjectTE; LLPointer<LLGLTFMaterial> mMaterial; + LLPointer<LLLocalGLTFMaterial> mLocalMaterial; }; LLSelectedTEGetMatData::LLSelectedTEGetMatData(bool for_override) @@ -262,48 +265,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; @@ -317,6 +335,7 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) LLMaterialEditor::LLMaterialEditor(const LLSD& key) : LLPreview(key) , mUnsavedChanges(0) + , mRevertedChanges(0) , mExpectedUploadCost(0) , mUploadingTexturesCount(0) { @@ -349,18 +368,35 @@ 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"); mMetallicTextureCtrl = getChild<LLTextureCtrl>("metallic_roughness_texture"); mEmissiveTextureCtrl = getChild<LLTextureCtrl>("emissive_texture"); mNormalTextureCtrl = getChild<LLTextureCtrl>("normal_texture"); + mBaseColorCtrl = getChild<LLColorSwatchCtrl>("base color"); + mEmissiveColorCtrl = getChild<LLColorSwatchCtrl>("emissive color"); + + mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); + mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); + mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); + mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); + + if (mIsOverride) + { + // Live editing needs a recovery mechanism on cancel + mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); + mMetallicTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); + mEmissiveTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); + mNormalTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); - mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitBaseColorTexture, this, _1, _2)); - mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2)); - mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2)); - mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2)); + // Save applied changes on 'OK' to our recovery mechanism. + mBaseColorTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); + mMetallicTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); + mEmissiveTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); + mNormalTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); + } if (!mIsOverride) { @@ -396,7 +432,13 @@ BOOL LLMaterialEditor::postBuild() childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY); // BaseColor - childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); + mBaseColorCtrl->setCommitCallback(changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); + if (mIsOverride) + { + mBaseColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY)); + mBaseColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY)); + } + // transparency is a part of base color childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY); childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY); @@ -406,7 +448,12 @@ BOOL LLMaterialEditor::postBuild() childSetCommitCallback("roughness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY); // Emissive - childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); + mEmissiveColorCtrl->setCommitCallback(changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); + if (mIsOverride) + { + mEmissiveColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY)); + mEmissiveColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY)); + } if (!mIsOverride) { @@ -510,14 +557,14 @@ void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id) LLColor4 LLMaterialEditor::getBaseColor() { - LLColor4 ret = linearColor4(LLColor4(childGetValue("base color"))); + LLColor4 ret = linearColor4(LLColor4(mBaseColorCtrl->getValue())); ret.mV[3] = getTransparency(); return ret; } void LLMaterialEditor::setBaseColor(const LLColor4& color) { - childSetValue("base color", srgbColor4(color).getValue()); + mBaseColorCtrl->setValue(srgbColor4(color).getValue()); setTransparency(color.mV[3]); } @@ -627,12 +674,12 @@ void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id) LLColor4 LLMaterialEditor::getEmissiveColor() { - return linearColor4(LLColor4(childGetValue("emissive color"))); + return linearColor4(LLColor4(mEmissiveColorCtrl->getValue())); } void LLMaterialEditor::setEmissiveColor(const LLColor4& color) { - childSetValue("emissive color", srgbColor4(color).getValue()); + mEmissiveColorCtrl->setValue(srgbColor4(color).getValue()); } LLUUID LLMaterialEditor::getNormalId() @@ -672,6 +719,7 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) void LLMaterialEditor::resetUnsavedChanges() { mUnsavedChanges = 0; + mRevertedChanges = 0; if (!mIsOverride) { childSetVisible("unsaved_changes", false); @@ -777,85 +825,142 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) mNormalTextureCtrl->setEnabled(can_modify); } -void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { if (!mIsOverride) { - // might be better to use arrays, to have a single callback - // and not to repeat the same thing for each tecture control - LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID(); - if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull()) + std::string upload_fee_ctrl_name; + LLUUID old_uuid; + + switch (dirty_flag) + { + case MATERIAL_BASE_COLOR_TEX_DIRTY: { - childSetValue("base_color_upload_fee", getString("upload_fee_string")); + upload_fee_ctrl_name = "base_color_upload_fee"; + old_uuid = mBaseColorTextureUploadId; + break; + } + case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: + { + upload_fee_ctrl_name = "metallic_upload_fee"; + old_uuid = mMetallicTextureUploadId; + break; + } + case MATERIAL_EMISIVE_TEX_DIRTY: + { + upload_fee_ctrl_name = "emissive_upload_fee"; + old_uuid = mEmissiveTextureUploadId; + break; + } + case MATERIAL_NORMAL_TEX_DIRTY: + { + upload_fee_ctrl_name = "normal_upload_fee"; + old_uuid = mNormalTextureUploadId; + break; + } + default: + break; + } + LLUUID new_val = ctrl->getValue().asUUID(); + if (new_val == old_uuid && old_uuid.notNull()) + { + childSetValue(upload_fee_ctrl_name, getString("upload_fee_string")); } else { // Texture picker has 'apply now' with 'cancel' support. - // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in - // case user decides to cancel changes. + // Don't clean mBaseColorJ2C and mBaseColorFetched, it's our + // storage in case user decides to cancel changes. // Without mBaseColorFetched, viewer will eventually cleanup // the texture that is not in use - childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); + childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } } - markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY); + + markChangesUnsaved(dirty_flag); applyToSelection(); } -void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { - if (!mIsOverride) - { - LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID(); - if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull()) - { - childSetValue("metallic_upload_fee", getString("upload_fee_string")); - } - else - { - childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); - } - } - markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); + mRevertedChanges |= dirty_flag; applyToSelection(); } -void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { - if (!mIsOverride) - { - LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID(); - if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull()) - { - childSetValue("emissive_upload_fee", getString("upload_fee_string")); - } - else - { - childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); - } - } - markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY); + mUnsavedChanges |= dirty_flag; applyToSelection(); -} -void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) -{ - if (!mIsOverride) + struct f : public LLSelectedNodeFunctor { - LLUUID new_val = mNormalTextureCtrl->getValue().asUUID(); - if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull()) + f(LLUICtrl* ctrl, S32 dirty_flag) : mCtrl(ctrl), mDirtyFlag(dirty_flag) { - childSetValue("normal_upload_fee", getString("upload_fee_string")); } - else + + virtual bool apply(LLSelectNode* nodep) { - childSetValue("normal_upload_fee", getString("no_upload_fee_string")); + LLViewerObject* objectp = nodep->getObject(); + if (!objectp) + { + return false; + } + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + for (S32 te = 0; te < num_tes; ++te) + { + if (nodep->isTESelected(te) && nodep->mSavedGLTFRenderMaterials.size() > te) + { + switch (mDirtyFlag) + { + //Textures + case MATERIAL_BASE_COLOR_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mBaseColorId = mCtrl->getValue().asUUID(); + break; + } + case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mMetallicRoughnessId = mCtrl->getValue().asUUID(); + break; + } + case MATERIAL_EMISIVE_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mEmissiveId = mCtrl->getValue().asUUID(); + break; + } + case MATERIAL_NORMAL_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mNormalId = mCtrl->getValue().asUUID(); + break; + } + // Colors + case MATERIAL_BASE_COLOR_DIRTY: + { + LLColor4 ret = linearColor4(LLColor4(mCtrl->getValue())); + // except transparency + ret.mV[3] = nodep->mSavedGLTFRenderMaterials[te]->mBaseColor.mV[3]; + nodep->mSavedGLTFRenderMaterials[te]->mBaseColor = ret; + break; + } + case MATERIAL_EMISIVE_COLOR_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mEmissiveColor = LLColor4(mCtrl->getValue()); + break; + } + default: + break; + } + } + } + return true; } - } - markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY); - applyToSelection(); -} + LLUICtrl* mCtrl; + S32 mDirtyFlag; + } func(ctrl, dirty_flag); + + LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func); +} static void write_color(const LLColor4& color, std::vector<double>& c) { @@ -1691,17 +1796,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 +1872,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)); } @@ -2182,7 +2342,7 @@ private: LLUUID mMatId; }; -class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor +class LLRenderMaterialOverrideFunctor : public LLSelectedNodeFunctor { public: LLRenderMaterialOverrideFunctor( @@ -2198,16 +2358,29 @@ public: { } - bool apply(LLViewerObject* objectp, S32 te) override + virtual bool apply(LLSelectNode* nodep) override { + LLViewerObject* objectp = nodep->getObject(); + if (!objectp || !objectp->permModify() || !objectp->getVolume()) + { + return false; + } + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + // post override from given object and te to the simulator // requestData should have: // object_id - UUID of LLViewerObject // side - S32 index of texture entry // gltf_json - String of GLTF json for override data - if (objectp && objectp->permModify() && objectp->getVolume()) + for (S32 te = 0; te < num_tes; ++te) { + if (!nodep->isTESelected(te)) + { + continue; + } + + // Get material from object // Selection can cover multiple objects, and live editor is // supposed to overwrite changed values only @@ -2221,59 +2394,114 @@ public: return false; } + // make a copy to not invalidate existing // material for multiple objects material = new LLGLTFMaterial(*material); + U32 changed_flags = mEditor->getUnsavedChangesFlags(); + U32 reverted_flags = mEditor->getRevertedChangesFlags(); + bool can_revert = nodep->mSavedGLTFRenderMaterials.size() > te; + // Override object's values with values from editor where appropriate - if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY) + if (changed_flags & MATERIAL_BASE_COLOR_DIRTY) { material->setBaseColorFactor(mEditor->getBaseColor(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY) + else if ((reverted_flags & MATERIAL_BASE_COLOR_DIRTY) && can_revert) + { + material->setBaseColorFactor(nodep->mSavedGLTFRenderMaterials[te]->mBaseColor, true); + } + + if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) { material->setBaseColorId(mEditor->getBaseColorId(), true); } + else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && can_revert) + { + material->setBaseColorId(nodep->mSavedGLTFRenderMaterials[te]->mBaseColorId, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY) + if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY) { material->setNormalId(mEditor->getNormalId(), true); } + else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && can_revert) + { + material->setNormalId(nodep->mSavedGLTFRenderMaterials[te]->mNormalId, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) + if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && can_revert) + { + material->setMetallicRoughnessId(nodep->mSavedGLTFRenderMaterials[te]->mMetallicRoughnessId, true); + } + + if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) { material->setMetallicFactor(mEditor->getMetalnessFactor(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) && can_revert) + { + material->setMetallicFactor(nodep->mSavedGLTFRenderMaterials[te]->mMetallicFactor, true); + } + + if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) { material->setRoughnessFactor(mEditor->getRoughnessFactor(), true); } + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) && can_revert) + { + material->setRoughnessFactor(nodep->mSavedGLTFRenderMaterials[te]->mRoughnessFactor, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY) + if (changed_flags & MATERIAL_EMISIVE_COLOR_DIRTY) { material->setEmissiveColorFactor(LLColor3(mEditor->getEmissiveColor()), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY) + else if ((reverted_flags & MATERIAL_EMISIVE_COLOR_DIRTY) && can_revert) + { + material->setEmissiveColorFactor(nodep->mSavedGLTFRenderMaterials[te]->mEmissiveColor, true); + } + + if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY) { material->setEmissiveId(mEditor->getEmissiveId(), true); } + else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && can_revert) + { + material->setEmissiveId(nodep->mSavedGLTFRenderMaterials[te]->mEmissiveId, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY) + if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) { material->setDoubleSided(mEditor->getDoubleSided(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY) + else if ((reverted_flags & MATERIAL_DOUBLE_SIDED_DIRTY) && can_revert) + { + material->setDoubleSided(nodep->mSavedGLTFRenderMaterials[te]->mDoubleSided, true); + } + + if (changed_flags & MATERIAL_ALPHA_MODE_DIRTY) { material->setAlphaMode(mEditor->getAlphaMode(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY) + else if ((reverted_flags & MATERIAL_ALPHA_MODE_DIRTY) && can_revert) + { + material->setAlphaMode(nodep->mSavedGLTFRenderMaterials[te]->mAlphaMode, true); + } + + if (changed_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) { material->setAlphaCutoff(mEditor->getAlphaCutoff(), true); } + else if ((reverted_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) && can_revert) + { + material->setAlphaCutoff(nodep->mSavedGLTFRenderMaterials[te]->mAlphaCutoff, true); + } #if 1 if (mObjectTE == te @@ -2344,12 +2572,12 @@ void LLMaterialEditor::applyToSelection() // Don't send data if there is nothing to send. // Some UI elements will cause multiple commits, // like spin ctrls on click and on down - if (mUnsavedChanges != 0) + if (mUnsavedChanges != 0 || mRevertedChanges != 0) { mOverrideInProgress = true; LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); LLRenderMaterialOverrideFunctor override_func(this, url, mOverrideObjectId, mOverrideObjectTE); - selected_objects->applyToTEs(&override_func); + selected_objects->applyToNodes(&override_func); void(*done_callback)(bool) = LLRenderMaterialOverrideFunctor::modifyCallback; @@ -2363,6 +2591,7 @@ void LLMaterialEditor::applyToSelection() // we posted all changes mUnsavedChanges = 0; + mRevertedChanges = 0; } } else diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 8f0c16881b..423e56e6c0 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -31,10 +31,11 @@ #include "llimagej2c.h" #include "llviewertexture.h" -class LLTextureCtrl; -class LLGLTFMaterial; class LLButton; +class LLColorSwatchCtrl; class LLComboBox; +class LLGLTFMaterial; +class LLTextureCtrl; class LLTextBox; namespace tinygltf @@ -218,15 +219,15 @@ public: void setCanSave(bool value); void setEnableEditing(bool can_modify); - void onCommitBaseColorTexture(LLUICtrl* ctrl, const LLSD& data); - void onCommitMetallicTexture(LLUICtrl* ctrl, const LLSD& data); - void onCommitEmissiveTexture(LLUICtrl* ctrl, const LLSD& data); - void onCommitNormalTexture(LLUICtrl* ctrl, const LLSD& data); + void onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); + void onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); + void onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); // initialize the UI from a default GLTF material void loadDefaults(); U32 getUnsavedChangesFlags() { return mUnsavedChanges; } + U32 getRevertedChangesFlags() { return mRevertedChanges; } bool capabilitiesAvalaible(); @@ -247,6 +248,8 @@ private: LLTextureCtrl* mMetallicTextureCtrl; LLTextureCtrl* mEmissiveTextureCtrl; LLTextureCtrl* mNormalTextureCtrl; + LLColorSwatchCtrl* mBaseColorCtrl; + LLColorSwatchCtrl* mEmissiveColorCtrl; // 'Default' texture, unless it's null or from inventory is the one with the fee LLUUID mBaseColorTextureUploadId; @@ -284,6 +287,7 @@ private: void markChangesUnsaved(U32 dirty_flag); U32 mUnsavedChanges; // flags to indicate individual changed parameters + U32 mRevertedChanges; // flags to indicate individual reverted parameters S32 mUploadingTexturesCount; S32 mExpectedUploadCost; std::string mMaterialNameShort; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 06f69e6fb5..ab6d4dc1d6 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -4374,10 +4374,26 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) if (te_data["te"].has("pbr")) { objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false); + + // todo: provide copied overrides here + LLCoros::instance().launch("modifyMaterialCoro", + std::bind(&LLGLTFMaterialList::modifyMaterialCoro, + gAgent.getRegionCapability("ModifyMaterialParams"), + llsd::map( + "object_id", objectp->getID(), + "side", te), nullptr)); } else { objectp->setRenderMaterialID(te, LLUUID::null, false); + + // blank out any override data on the server + LLCoros::instance().launch("modifyMaterialCoro", + std::bind(&LLGLTFMaterialList::modifyMaterialCoro, + gAgent.getRegionCapability("ModifyMaterialParams"), + llsd::map( + "object_id", objectp->getID(), + "side", te), nullptr)); } // Texture map diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index e4a67d7982..fa9604ef9d 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1812,6 +1812,14 @@ void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item) // apply texture for the selected faces //add(LLStatViewer::EDIT_TEXTURE, 1); object->setRenderMaterialID(te, asset_id, false /*will be sent later*/); + + // blank out any override data on the server + LLCoros::instance().launch("modifyMaterialCoro", + std::bind(&LLGLTFMaterialList::modifyMaterialCoro, + gAgent.getRegionCapability("ModifyMaterialParams"), + llsd::map( + "object_id", object->getID(), + "side", te), nullptr)); } } } @@ -1948,7 +1956,15 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/); } - objectp->setRenderMaterialID(te, asset_id); + objectp->setRenderMaterialID(te, asset_id, false /*prevent an update to prevent a race condition*/); + + // blank out any override data on the server + LLCoros::instance().launch("modifyMaterialCoro", + std::bind(&LLGLTFMaterialList::modifyMaterialCoro, + gAgent.getRegionCapability("ModifyMaterialParams"), + llsd::map( + "object_id", objectp->getID(), + "side", te), nullptr)); return true; } @@ -1978,6 +1994,8 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); if (param_block) { + // To not cause multiple competing request that modify + // same param field send update only once per object if (param_block->isEmpty()) { object->setHasRenderMaterialParams(false); @@ -2197,10 +2215,31 @@ void LLSelectMgr::selectionRevertGLTFMaterials() } LLSelectNode* nodep = mSelectedObjects->findNode(objectp); - if (nodep && te < (S32)nodep->mSavedGLTFMaterials.size()) + if (nodep && te < (S32)nodep->mSavedGLTFMaterialIds.size()) { - LLUUID asset_id = nodep->mSavedGLTFMaterials[te]; + // Restore base material + LLUUID asset_id = nodep->mSavedGLTFMaterialIds[te]; objectp->setRenderMaterialID(te, asset_id, false /*wait for bulk update*/); + + // Restore overrides + LLSD overrides; + overrides["object_id"] = objectp->getID(); + overrides["side"] = te; + + // todo: make sure this does not cause race condition with setRenderMaterialID + // when we are reverting from null id to non null plus override + if (te < (S32)nodep->mSavedGLTFRenderMaterials.size() + && nodep->mSavedGLTFRenderMaterials[te].notNull() + && asset_id.notNull()) + { + overrides["gltf_json"] = nodep->mSavedGLTFRenderMaterials[te]->asJSON(); + } // else nothing to blank override out + + LLCoros::instance().launch("modifyMaterialCoro", + std::bind(&LLGLTFMaterialList::modifyMaterialCoro, + gAgent.getRegionCapability("ModifyMaterialParams"), + overrides, + nullptr)); } return true; } @@ -5830,12 +5869,33 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data if (can_copy && can_transfer && node->getObject()->getVolume()) { uuid_vec_t material_ids; + gltf_materials_vec_t materials; LLVOVolume* vobjp = (LLVOVolume*)node->getObject(); for (int i = 0; i < vobjp->getNumTEs(); ++i) { material_ids.push_back(vobjp->getRenderMaterialID(i)); + + // Make a copy to ensure we won't affect live material + // with any potential changes nor live changes will be + // reflected in a saved copy. + // Like changes from local material (reuses pointer) or + // from live editor (revert mechanics might modify this) + LLGLTFMaterial* old_mat = node->getObject()->getTE(i)->getGLTFRenderMaterial(); + if (old_mat) + { + LLPointer<LLGLTFMaterial> mat = new LLGLTFMaterial(*old_mat); + materials.push_back(mat); + } + else + { + materials.push_back(nullptr); + } } - node->savedGLTFMaterials(material_ids); + node->saveGLTFMaterialIds(material_ids); + + // processObjectProperties does not include overrides so this + // might need to be moved to LLGLTFMaterialOverrideDispatchHandler + node->saveGLTFRenderMaterials(materials); } } @@ -6588,7 +6648,8 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep) } saveTextures(nodep.mSavedTextures); - savedGLTFMaterials(nodep.mSavedGLTFMaterials); + saveGLTFMaterialIds(nodep.mSavedGLTFMaterialIds); + saveGLTFRenderMaterials(nodep.mSavedGLTFRenderMaterials); } LLSelectNode::~LLSelectNode() @@ -6722,20 +6783,43 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures) } } -void LLSelectNode::savedGLTFMaterials(const uuid_vec_t& materials) +void LLSelectNode::saveGLTFMaterialIds(const uuid_vec_t& materials) { if (mObject.notNull()) { - mSavedGLTFMaterials.clear(); + mSavedGLTFMaterialIds.clear(); for (uuid_vec_t::const_iterator materials_it = materials.begin(); materials_it != materials.end(); ++materials_it) { - mSavedGLTFMaterials.push_back(*materials_it); + mSavedGLTFMaterialIds.push_back(*materials_it); } } } +void LLSelectNode::saveGLTFRenderMaterials(const gltf_materials_vec_t& materials) +{ + if (mObject.notNull()) + { + mSavedGLTFRenderMaterials.clear(); + + for (gltf_materials_vec_t::const_iterator mat_it = materials.begin(); + mat_it != materials.end(); ++mat_it) + { + mSavedGLTFRenderMaterials.push_back(*mat_it); + } + } +} + +LLGLTFMaterial* LLSelectNode::getSavedGLTFRenderMaterial(S32 te) +{ + if (mSavedGLTFRenderMaterials.size() > te) + { + return mSavedGLTFRenderMaterials[te].get(); + } + return nullptr; +} + void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) { mTextureScaleRatios.clear(); diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 573eea7a8a..7e7c450767 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -161,6 +161,8 @@ typedef enum e_selection_type SELECT_TYPE_HUD }ESelectType; +typedef std::vector<LLPointer<LLGLTFMaterial> > gltf_materials_vec_t; + const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; // Contains information about a selected object, particularly which TEs are selected. @@ -184,12 +186,21 @@ public: LLViewerObject* getObject(); void setObject(LLViewerObject* object); // *NOTE: invalidate stored textures and colors when # faces change + // Used by tools floater's color/texture pickers to restore changes void saveColors(); void saveShinyColors(); void saveTextures(const uuid_vec_t& textures); - void savedGLTFMaterials(const uuid_vec_t& materials); void saveTextureScaleRatios(LLRender::eTexIndex index_to_query); + // GLTF materials are applied to objects by ids, + // overrides get applied on top of materials resulting in + // final gltf material that users see. + // Ids get applied and restored by tools floater, + // overrides get applied in live material editor + void saveGLTFMaterialIds(const uuid_vec_t& materials); + void saveGLTFRenderMaterials(const gltf_materials_vec_t& materials); + LLGLTFMaterial* getSavedGLTFRenderMaterial(S32 te); + BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const; public: @@ -225,7 +236,8 @@ public: std::vector<LLColor4> mSavedColors; std::vector<LLColor4> mSavedShinyColors; uuid_vec_t mSavedTextures; - uuid_vec_t mSavedGLTFMaterials; + uuid_vec_t mSavedGLTFMaterialIds; + gltf_materials_vec_t mSavedGLTFRenderMaterials; std::vector<LLVector3> mTextureScaleRatios; std::vector<LLVector3> mSilhouetteVertices; // array of vertices to render silhouette of object std::vector<LLVector3> mSilhouetteNormals; // array of normals to render silhouette of object diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index cff26ea51f..05587af9bc 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, 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, diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index a649387795..1efc4ea3d5 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -7215,25 +7215,30 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat "object_id", getID(), "side", te), nullptr)); } + } - // update and send LLRenderMaterialParams - LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); - if (!param_block && id.notNull()) - { // block doesn't exist, but it will need to - param_block = (LLRenderMaterialParams*) createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data; - } + // update and send LLRenderMaterialParams + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (!param_block && id.notNull()) + { // block doesn't exist, but it will need to + param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data; + } - if (param_block) - { // update existing parameter block - for (S32 te = start_idx; te < end_idx; ++te) - { - param_block->setMaterial(te, id); - } + if (param_block) + { // update existing parameter block + for (S32 te = start_idx; te < end_idx; ++te) + { + param_block->setMaterial(te, id); + } + if (update_server) + { + // If 'in use' changes, it will send an update itself. bool in_use_changed = setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, !param_block->isEmpty(), true); if (!in_use_changed) - { // in use didn't change, but the parameter did + { + // In use didn't change, but the parameter did, send an update parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, param_block, !param_block->isEmpty(), true); } } |