diff options
Diffstat (limited to 'indra')
| -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);              }          }  | 
