Merge branch 'DRTVWR-559' of https://bitbucket.org/lindenlab/viewer
commit
f4a99d354c
|
|
@ -286,3 +286,4 @@ else (USESYSTEMLIBS)
|
|||
endif (USESYSTEMLIBS)
|
||||
|
||||
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -154,6 +154,8 @@ private:
|
|||
LLView* mDAE;
|
||||
LLView* mDAN;
|
||||
LLView* mDAF;
|
||||
|
||||
boost::signals2::connection mSelectionUpdateSlot;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 >"
|
||||
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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue