summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/lllocalgltfmaterials.cpp48
-rw-r--r--indra/newview/lllocalgltfmaterials.h21
-rw-r--r--indra/newview/llmaterialeditor.cpp461
-rw-r--r--indra/newview/llmaterialeditor.h16
-rw-r--r--indra/newview/llpanelface.cpp16
-rw-r--r--indra/newview/llselectmgr.cpp100
-rw-r--r--indra/newview/llselectmgr.h16
-rw-r--r--indra/newview/lltinygltfhelper.cpp11
-rw-r--r--indra/newview/lltinygltfhelper.h6
-rw-r--r--indra/newview/llviewerobject.cpp31
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);
}
}