meow-7.2.2
Ansariel 2022-10-26 21:28:06 +02:00
commit f4a99d354c
15 changed files with 424 additions and 94 deletions

View File

@ -286,3 +286,4 @@ else (USESYSTEMLIBS)
endif (USESYSTEMLIBS)
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)

View File

@ -519,6 +519,17 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material)
}
}
LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const
{
if (mGLTFRenderMaterial.notNull())
{
return mGLTFRenderMaterial;
}
llassert(getGLTFMaterialOverride() == nullptr);
return getGLTFMaterial();
}
S32 LLTextureEntry::setGLTFRenderMaterial(LLGLTFMaterial* mat)
{
if (mGLTFRenderMaterial != mat)

View File

@ -199,12 +199,12 @@ public:
LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; }
// GLTF override
LLGLTFMaterial* getGLTFMaterialOverride() { return mGLTFMaterialOverrides; }
LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; }
void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = mat; }
// GLTF render material
// nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter
LLGLTFMaterial* getGLTFRenderMaterial() const { return mGLTFRenderMaterial.notNull() ? mGLTFRenderMaterial.get() : getGLTFMaterial(); }
LLGLTFMaterial* getGLTFRenderMaterial() const;
S32 setGLTFRenderMaterial(LLGLTFMaterial* mat);
public:

View File

@ -43,6 +43,8 @@
#include "json/reader.h"
#include "json/value.h"
LLGLTFMaterialList gGLTFMaterialList;
namespace
{
class LLGLTFMaterialOverrideDispatchHandler : public LLDispatchHandler
@ -72,24 +74,27 @@ namespace
LL_WARNS() << "LLGLTFMaterialOverrideDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
}
}
LLUUID object_id = message["object_id"].asUUID();
LLViewerObject * obj = gObjectList.findObject(message["object_id"].asUUID());
llassert(obj); // should never get an override for an object we don't know about
LLViewerObject * obj = gObjectList.findObject(object_id);
S32 side = message["side"].asInteger();
std::string gltf_json = message["gltf_json"].asString();
std::string warn_msg, error_msg;
LLPointer<LLGLTFMaterial> override_data = new LLGLTFMaterial();
bool success = override_data->fromJSON(gltf_json, warn_msg, error_msg);
if (!success)
{
LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL;
}
else
{
if (obj)
if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data))
{
obj->setTEGLTFMaterialOverride(side, override_data);
// object not ready to receive override data, queue for later
gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data);
}
}
@ -99,7 +104,41 @@ namespace
LLGLTFMaterialOverrideDispatchHandler handle_gltf_override_message;
}
LLGLTFMaterialList gGLTFMaterialList;
void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data)
{
override_list_t& overrides = mQueuedOverrides[id];
if (overrides.size() < side + 1)
{
overrides.resize(side + 1);
}
overrides[side] = override_data;
}
void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj)
{
const LLUUID& id = obj->getID();
auto iter = mQueuedOverrides.find(id);
if (iter != mQueuedOverrides.end())
{
override_list_t& overrides = iter->second;
for (int i = 0; i < overrides.size(); ++i)
{
if (overrides[i].notNull())
{
if (!obj->getTE(i)->getGLTFMaterial())
{ // object doesn't have its base GLTF material yet, don't apply override (yet)
return;
}
obj->setTEGLTFMaterialOverride(i, overrides[i]);
}
}
mQueuedOverrides.erase(iter);
}
}
LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
{

View File

@ -48,10 +48,20 @@ public:
void flushMaterials();
static void registerCallbacks();
// save an override update for later (for example, if an override arrived for an unknown object)
void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data);
void applyQueuedOverrides(LLViewerObject* obj);
private:
typedef std::unordered_map<LLUUID, LLPointer<LLFetchedGLTFMaterial > > uuid_mat_map_t;
uuid_mat_map_t mList;
typedef std::vector<LLPointer<LLGLTFMaterial> > override_list_t;
typedef std::unordered_map<LLUUID, override_list_t > queued_override_map_t;
queued_override_map_t mQueuedOverrides;
LLUUID mLastUpdateKey;
};

View File

@ -122,6 +122,7 @@ private:
viewer_media_t mMediaImpl;
LLMediaEntry* mMediaEntry;
LLSafeHandle<LLObjectSelection> mObjectSelection;
boost::signals2::connection mSelectionUpdateSlot;
};
LLInspectObject::LLInspectObject(const LLSD& sd)
@ -147,6 +148,10 @@ LLInspectObject::LLInspectObject(const LLSD& sd)
LLInspectObject::~LLInspectObject()
{
if (mSelectionUpdateSlot.connected())
{
mSelectionUpdateSlot.disconnect();
}
}
/*virtual*/
@ -181,9 +186,12 @@ BOOL LLInspectObject::postBuild(void)
getChild<LLUICtrl>("more_info_btn")->setCommitCallback(
boost::bind(&LLInspectObject::onClickMoreInfo, this));
// Watch for updates to selection properties off the network
LLSelectMgr::getInstance()->mUpdateSignal.connect(
boost::bind(&LLInspectObject::update, this) );
if (!mSelectionUpdateSlot.connected())
{
// Watch for updates to selection properties off the network
mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(
boost::bind(&LLInspectObject::update, this));
}
return TRUE;
}

View File

@ -67,6 +67,24 @@ const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive";
const LLUUID LIVE_MATERIAL_EDITOR_KEY("6cf97162-8b68-49eb-b627-79886c9fd17d");
// Dirty flags
static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0;
static const U32 MATERIAL_BASE_TRANSPARENCY_DIRTY = 0x1 << 1;
static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 2;
static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 3;
static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 4;
static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 5;
static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 6;
static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 7;
static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 8;
static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 9;
static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 10;
static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 11;
LLFloaterComboOptions::LLFloaterComboOptions()
: LLFloater(LLSD())
{
@ -199,7 +217,7 @@ private:
// Default constructor
LLMaterialEditor::LLMaterialEditor(const LLSD& key)
: LLPreview(key)
, mHasUnsavedChanges(false)
, mUnsavedChanges(0)
, mExpectedUploadCost(0)
, mUploadingTexturesCount(0)
{
@ -251,33 +269,30 @@ BOOL LLMaterialEditor::postBuild()
getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void*)
boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void* userData)
{
setHasUnsavedChanges(true);
const U32 *flag = (const U32*)userData;
markChangesUnsaved(*flag);
// Apply changes to object live
applyToSelection();
};
childSetCommitCallback("double sided", changes_callback, NULL);
childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY);
// BaseColor
childSetCommitCallback("base color", changes_callback, NULL);
childSetCommitCallback("transparency", changes_callback, NULL);
childSetCommitCallback("alpha mode", changes_callback, NULL);
childSetCommitCallback("alpha cutoff", changes_callback, NULL);
childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY);
childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_TRANSPARENCY_DIRTY);
childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY);
childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY);
// Metallic-Roughness
childSetCommitCallback("metalness factor", changes_callback, NULL);
childSetCommitCallback("roughness factor", changes_callback, NULL);
// Metallic-Roughness
childSetCommitCallback("metalness factor", changes_callback, NULL);
childSetCommitCallback("roughness factor", changes_callback, NULL);
childSetCommitCallback("metalness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY);
childSetCommitCallback("roughness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY);
// Emissive
childSetCommitCallback("emissive color", changes_callback, NULL);
childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY);
childSetVisible("unsaved_changes", mHasUnsavedChanges);
childSetVisible("unsaved_changes", mUnsavedChanges);
getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0));
@ -302,10 +317,11 @@ void LLMaterialEditor::onClickCloseBtn(bool app_quitting)
void LLMaterialEditor::onClose(bool app_quitting)
{
// todo: will only revert whatever was recently selected,
// Later should work based of tools floater
LLSelectMgr::getInstance()->selectionRevertGLTFMaterials();
if (mSelectionUpdateSlot.connected())
{
mSelectionUpdateSlot.disconnect();
}
LLPreview::onClose(app_quitting);
}
@ -332,7 +348,7 @@ void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id)
// Only set if we will need to upload this texture
mBaseColorTextureUploadId = id;
}
setHasUnsavedChanges(true);
markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY);
}
LLColor4 LLMaterialEditor::getBaseColor()
@ -404,7 +420,7 @@ void LLMaterialEditor::setMetallicRoughnessUploadId(const LLUUID& id)
childSetValue("metallic_upload_fee", getString("upload_fee_string"));
mMetallicTextureUploadId = id;
}
setHasUnsavedChanges(true);
markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
}
F32 LLMaterialEditor::getMetalnessFactor()
@ -447,7 +463,7 @@ void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id)
childSetValue("emissive_upload_fee", getString("upload_fee_string"));
mEmissiveTextureUploadId = id;
}
setHasUnsavedChanges(true);
markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY);
}
LLColor4 LLMaterialEditor::getEmissiveColor()
@ -480,7 +496,7 @@ void LLMaterialEditor::setNormalUploadId(const LLUUID& id)
childSetValue("normal_upload_fee", getString("upload_fee_string"));
mNormalTextureUploadId = id;
}
setHasUnsavedChanges(true);
markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY);
}
bool LLMaterialEditor::getDoubleSided()
@ -493,12 +509,22 @@ void LLMaterialEditor::setDoubleSided(bool double_sided)
childSetValue("double sided", double_sided);
}
void LLMaterialEditor::setHasUnsavedChanges(bool value)
void LLMaterialEditor::resetUnsavedChanges()
{
mHasUnsavedChanges = value;
childSetVisible("unsaved_changes", value);
mUnsavedChanges = 0;
childSetVisible("unsaved_changes", false);
setCanSave(false);
if (mHasUnsavedChanges)
mExpectedUploadCost = 0;
getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost));
}
void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag)
{
mUnsavedChanges |= dirty_flag;
childSetVisible("unsaved_changes", mUnsavedChanges);
if (mUnsavedChanges)
{
const LLInventoryItem* item = getItem();
if (item)
@ -593,7 +619,7 @@ void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & da
// the texture that is not in use
childSetValue("base_color_upload_fee", getString("no_upload_fee_string"));
}
setHasUnsavedChanges(true);
markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY);
applyToSelection();
}
@ -608,7 +634,7 @@ void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & dat
{
childSetValue("metallic_upload_fee", getString("no_upload_fee_string"));
}
setHasUnsavedChanges(true);
markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
applyToSelection();
}
@ -623,7 +649,7 @@ void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & dat
{
childSetValue("emissive_upload_fee", getString("no_upload_fee_string"));
}
setHasUnsavedChanges(true);
markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY);
applyToSelection();
}
@ -638,7 +664,7 @@ void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data)
{
childSetValue("normal_upload_fee", getString("no_upload_fee_string"));
}
setHasUnsavedChanges(true);
markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY);
applyToSelection();
}
@ -1222,7 +1248,7 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD&
else
{
std::string buffer = getEncodedAsset();
LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mHasUnsavedChanges);
LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mUnsavedChanges);
copy_inventory_item(
gAgent.getID(),
item->getPermissions().getOwner(),
@ -1250,7 +1276,7 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD&
void LLMaterialEditor::onClickCancel()
{
if (mHasUnsavedChanges)
if (mUnsavedChanges)
{
LLNotificationsUtil::add("UsavedMaterialChanges", LLSD(), LLSD(), boost::bind(&LLMaterialEditor::onCancelMsgCallback, this, _1, _2));
}
@ -1265,6 +1291,73 @@ void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD&
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (0 == option)
{
if (mIsOverride && !mObjectOverridesSavedValues.empty())
{
// Reapply ids back onto selection.
// TODO: monitor selection changes and resave on selection changes
struct g : public LLSelectedObjectFunctor
{
g(LLMaterialEditor* me) : mEditor(me) {}
virtual bool apply(LLViewerObject* objectp)
{
if (!objectp || !objectp->permModify())
{
return false;
}
U32 local_id = objectp->getLocalID();
if (mEditor->mObjectOverridesSavedValues.find(local_id) == mEditor->mObjectOverridesSavedValues.end())
{
return false;
}
S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
for (U8 te = 0; te < num_tes; te++)
{
if (mEditor->mObjectOverridesSavedValues[local_id].size() > te
&& objectp->getTE(te)->isSelected())
{
objectp->setRenderMaterialID(
te,
mEditor->mObjectOverridesSavedValues[local_id][te],
false /*wait for bulk update*/);
}
}
return true;
}
LLMaterialEditor* mEditor;
} restorefunc(this);
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&restorefunc);
struct f : public LLSelectedObjectFunctor
{
virtual bool apply(LLViewerObject* object)
{
if (object && !object->permModify())
{
return false;
}
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
if (param_block)
{
if (param_block->isEmpty())
{
object->setHasRenderMaterialParams(false);
}
else
{
object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
}
}
object->sendTEUpdate();
return true;
}
} sendfunc;
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
}
closeFloater();
}
}
@ -1400,17 +1493,62 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind
);
}
}
void LLMaterialEditor::onSelectionChanged()
{
mUnsavedChanges = 0;
clearTextures();
setFromSelection();
saveLiveValues();
}
void LLMaterialEditor::saveLiveValues()
{
// Collect ids to be able to revert overrides.
// TODO: monitor selection changes and resave on selection changes
mObjectOverridesSavedValues.clear();
struct g : public LLSelectedObjectFunctor
{
g(LLMaterialEditor* me) : mEditor(me) {}
virtual bool apply(LLViewerObject* objectp)
{
if (!objectp)
{
return false;
}
U32 local_id = objectp->getLocalID();
S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
for (U8 te = 0; te < num_tes; te++)
{
LLUUID mat_id = objectp->getRenderMaterialID(te);
mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id);
}
return true;
}
LLMaterialEditor* mEditor;
} savefunc(this);
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc);
}
void LLMaterialEditor::loadLive()
{
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY));
if (me->setFromSelection())
if (me)
{
me->setFromSelection();
me->mIsOverride = true;
me->setTitle(me->getString("material_override_title"));
me->childSetVisible("save", false);
me->childSetVisible("save_as", false);
// Set up for selection changes updates
if (!me->mSelectionUpdateSlot.connected())
{
me->mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLMaterialEditor::onSelectionChanged, me));
}
// Collect ids to be able to revert overrides on cancel.
me->saveLiveValues();
me->openFloater();
me->setFocus(TRUE);
}
@ -1438,7 +1576,6 @@ void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id)
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
me->mMaterialName = LLTrans::getString("New Material");
me->setTitle(me->mMaterialName);
me->setHasUnsavedChanges(true);
me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id));
me->openFloater();
me->setFocus(TRUE);
@ -1540,7 +1677,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::
setFromGltfMetaData(filename_lc, model_in, index);
setHasUnsavedChanges(true);
markChangesUnsaved(U32_MAX);
openFloater();
setFocus(TRUE);
@ -1878,8 +2015,8 @@ private:
class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor
{
public:
LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url, LLUUID const & asset_id)
: mEditor(me), mCapUrl(url), mAssetID(asset_id)
LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url)
: mEditor(me), mCapUrl(url)
{
}
@ -1894,9 +2031,69 @@ public:
if (objectp && objectp->permModify() && objectp->getVolume())
{
LLPointer<LLGLTFMaterial> material = new LLGLTFMaterial();
mEditor->getGLTFMaterial(material);
// Get material from object
// Selection can cover multiple objects, and live editor is
// supposed to overwrite changed values only
LLTextureEntry* tep = objectp->getTE(te);
LLPointer<LLGLTFMaterial> material = tep->getGLTFMaterial();
if (material.isNull())
{
material = new LLGLTFMaterial();
}
// Override object's values with values from editor where appropriate
if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY)
{
material->mBaseColor = mEditor->getBaseColor();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_TRANSPARENCY_DIRTY)
{
material->mBaseColor.mV[3] = mEditor->getTransparency();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY)
{
material->mBaseColorId = mEditor->getBaseColorId();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY)
{
material->mNormalId = mEditor->getNormalId();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)
{
material->mMetallicRoughnessId = mEditor->getMetallicRoughnessId();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY)
{
material->mMetallicFactor = mEditor->getMetalnessFactor();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY)
{
material->mRoughnessFactor = mEditor->getRoughnessFactor();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY)
{
material->mEmissiveColor = mEditor->getEmissiveColor();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY)
{
material->mEmissiveId = mEditor->getEmissiveId();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY)
{
material->mDoubleSided = mEditor->getDoubleSided();
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY)
{
material->setAlphaMode(mEditor->getAlphaMode());
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY)
{
material->mAlphaCutoff = mEditor->getAlphaCutoff();
}
std::string overrides_json = material->asJSON();
@ -1913,7 +2110,6 @@ public:
private:
LLMaterialEditor * mEditor;
std::string mCapUrl;
LLUUID mAssetID;
};
void LLMaterialEditor::applyToSelection()
@ -1932,7 +2128,7 @@ void LLMaterialEditor::applyToSelection()
{
LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
// TODO figure out how to get the right asset id in cases where we don't have a good one
LLRenderMaterialOverrideFunctor override_func(this, url, mAssetID);
LLRenderMaterialOverrideFunctor override_func(this, url);
selected_objects->applyToTEs(&override_func);
}
else
@ -2006,6 +2202,10 @@ bool LLMaterialEditor::setFromSelection()
return true;
}
// pick defaults from a blank material;
LLGLTFMaterial blank_mat;
setFromGLTFMaterial(&blank_mat);
return false;
}
@ -2045,7 +2245,7 @@ void LLMaterialEditor::loadAsset()
{
mAssetStatus = PREVIEW_ASSET_LOADED;
loadDefaults();
setHasUnsavedChanges(false);
resetUnsavedChanges();
setEnableEditing(allow_modify && !source_library);
}
else
@ -2070,7 +2270,7 @@ void LLMaterialEditor::loadAsset()
LL_WARNS() << "Can't find object " << mObjectUUID << " associated with notecard." << LL_ENDL;
mAssetID.setNull();
mAssetStatus = PREVIEW_ASSET_LOADED;
setHasUnsavedChanges(false);
resetUnsavedChanges();
setEnableEditing(allow_modify && !source_library);
return;
}
@ -2157,7 +2357,7 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid,
BOOL allow_modify = editor->canModify(editor->mObjectUUID, editor->getItem());
BOOL source_library = editor->mObjectUUID.isNull() && gInventory.isObjectDescendentOf(editor->mItemUUID, gInventory.getLibraryRootFolderID());
editor->setEnableEditing(allow_modify && !source_library);
editor->setHasUnsavedChanges(false);
editor->resetUnsavedChanges();
editor->mAssetStatus = PREVIEW_ASSET_LOADED;
editor->setEnabled(true); // ready for use
}
@ -2335,6 +2535,16 @@ S32 LLMaterialEditor::saveTextures()
}
// discard upload buffers once textures have been saved
clearTextures();
// asset storage can callback immediately, causing a decrease
// of mUploadingTexturesCount, report amount of work scheduled
// not amount of work remaining
return work_count;
}
void LLMaterialEditor::clearTextures()
{
mBaseColorJ2C = nullptr;
mNormalJ2C = nullptr;
mEmissiveJ2C = nullptr;
@ -2349,11 +2559,6 @@ S32 LLMaterialEditor::saveTextures()
mNormalTextureUploadId.setNull();
mMetallicTextureUploadId.setNull();
mEmissiveTextureUploadId.setNull();
// asset storage can callback immediately, causing a decrease
// of mUploadingTexturesCount, report amount of work scheduled
// not amount of work remaining
return work_count;
}
void LLMaterialEditor::loadDefaults()

View File

@ -103,6 +103,8 @@ public:
// will promt to select specific one
static void loadMaterialFromFile(const std::string& filename, S32 index = -1);
void onSelectionChanged(); // // live overrides selection changes
void saveLiveValues(); // for restoration on cancel
static void loadLive();
static void loadObjectSave();
@ -118,6 +120,7 @@ public:
// save textures to inventory if needed
// returns amount of scheduled uploads
S32 saveTextures();
void clearTextures();
void onClickSave();
@ -206,7 +209,6 @@ public:
bool getDoubleSided();
void setDoubleSided(bool double_sided);
void setHasUnsavedChanges(bool value);
void setCanSaveAs(bool value);
void setCanSave(bool value);
void setEnableEditing(bool can_modify);
@ -221,6 +223,8 @@ public:
void modifyMaterialCoro(std::string cap_url, LLSD overrides);
U32 getUnsavedChangesFlags() { return mUnsavedChanges; }
private:
void setFromGLTFMaterial(LLGLTFMaterial* mat);
bool setFromSelection();
@ -268,7 +272,10 @@ private:
// based on what we know about it.
const std::string buildMaterialDescription();
bool mHasUnsavedChanges;
void resetUnsavedChanges();
void markChangesUnsaved(U32 dirty_flag);
U32 mUnsavedChanges; // flags to indicate individual changed parameters
S32 mUploadingTexturesCount;
S32 mExpectedUploadCost;
std::string mMaterialNameShort;
@ -276,5 +283,9 @@ private:
// if true, this instance is live instance editing overrides
bool mIsOverride = false;
// local id, texture ids per face for object overrides
// for "cancel" support
std::map<U32, uuid_vec_t> mObjectOverridesSavedValues;
boost::signals2::connection mSelectionUpdateSlot;
};

View File

@ -81,7 +81,7 @@ static LLPanelInjector<LLSidepanelTaskInfo> t_task_info("sidepanel_task_info");
LLSidepanelTaskInfo::LLSidepanelTaskInfo()
{
setMouseOpaque(FALSE);
LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this));
mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this));
}
@ -89,6 +89,11 @@ LLSidepanelTaskInfo::~LLSidepanelTaskInfo()
{
if (sActivePanel == this)
sActivePanel = NULL;
if (mSelectionUpdateSlot.connected())
{
mSelectionUpdateSlot.disconnect();
}
}
// virtual

View File

@ -154,6 +154,8 @@ private:
LLView* mDAE;
LLView* mDAN;
LLView* mDAF;
boost::signals2::connection mSelectionUpdateSlot;
};

View File

@ -3625,30 +3625,20 @@ void handle_object_edit()
return;
}
void load_life_gltf_material(bool copy)
void handle_object_edit_gltf_material()
{
update_camera();
LLSelectedTEGetmatIdAndPermissions func;
LLUUID mat_id;
LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat_id);
if (copy)
if (!LLFloaterReg::instanceVisible("build"))
{
LLMaterialEditor::loadFromGLTFMaterial(mat_id);
handle_object_edit(); // does update_camera();
}
else
{
LLMaterialEditor::loadLive();
update_camera();
LLViewerJoystick::getInstance()->moveObjects(true);
LLViewerJoystick::getInstance()->setNeedsReset(true);
}
LLViewerJoystick::getInstance()->moveObjects(true);
LLViewerJoystick::getInstance()->setNeedsReset(true);
}
void handle_object_edit_gltf_material()
{
handle_object_edit();
LLMaterialEditor::loadLive();
}

View File

@ -265,6 +265,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL;
res = NULL; break;
}
return res;
}
@ -5497,8 +5498,8 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
LLTextureEntry* tep = getTE(te);
if (!tep)
{
LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
{ // this could happen if the object is not fully formed yet
// returning TEM_CHANGE_NONE here signals to LLGLTFMaterialList to queue the override for later
return retval;
}
@ -5507,7 +5508,7 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
tep->setGLTFMaterialOverride(override_mat);
// if override mat exists, we must also have a source mat
llassert(override_mat ? src_mat : true);
llassert(override_mat ? bool(src_mat) : true);
if (override_mat && src_mat)
{

View File

@ -88,6 +88,7 @@
#include "llcallstack.h"
#include "llsculptidsize.h"
#include "llavatarappearancedefines.h"
#include "llgltfmateriallist.h"
// [RLVa:KB] - Checked: RLVa-2.0.0
#include "rlvactions.h"
#include "rlvlocks.h"
@ -6107,6 +6108,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
// apply any pending material overrides
gGLTFMaterialList.applyQueuedOverrides(vobj);
//<FS:Beq> Stop doing stupid stuff we don;t need to.
// Moving this inside a debug enabled check

View File

@ -32,6 +32,22 @@
<menu_item_call.on_enable
function="EnableEdit" />
</menu_item_call>
<menu_item_call
label="Edit PBR Material"
name="EditGLTFMaterial">
<menu_item_call.on_click
function="Object.EditGLTFMaterial" />
<menu_item_call.on_enable
function="Object.EnableEditGLTFMaterial"/>
</menu_item_call>
<menu_item_call
label="Save material to inventory"
name="SaveGLTFMaterial">
<menu_item_call.on_click
function="Object.SaveGLTFMaterial" />
<menu_item_call.on_enable
function="Object.EnableSaveGLTFMaterial"/>
</menu_item_call>
<menu_item_call
enabled="false"
label="Detach"

View File

@ -219,14 +219,42 @@
</pie_menu>
<pie_slice
enabled="false"
label="Edit"
name="Edit...">
<pie_slice.on_click
function="Object.Edit" />
<pie_slice.on_enable
function="EnableEdit" />
</pie_slice>
<pie_menu
label="Edit &gt;"
name="Edit Object Pie More 1">
<pie_slice
label="Edit Mat."
name="EditGLTFMaterial">
<pie_slice.on_click
function="Object.EditGLTFMaterial" />
<pie_slice.on_enable
function="EnableEditGLTFMaterial"/>
</pie_slice>
<pie_slice
label="Save Mat."
name="SaveGLTFMaterial">
<pie_slice.on_click
function="Object.SaveGLTFMaterial" />
<pie_slice.on_enable
function="EnableSaveGLTFMaterial"/>
</pie_slice>
<pie_separator/>
<pie_separator/>
<pie_separator/>
<pie_separator/>
<pie_separator/>
<pie_slice
label="Edit Object"
name="Edit...">
<pie_slice.on_click
function="Object.Edit" />
<pie_slice.on_enable
function="EnableEdit"/>
</pie_slice>
</pie_menu>
</pie_menu>