summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-10-17 23:33:27 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-10-17 23:33:27 +0300
commita27e701530e3498f71b828d7639024330cd0ccb7 (patch)
tree3d54a904e2bd92c6d556c18ecde146b0855b0b89
parent5fc91f6911ec2e2749ac26766595840b34807875 (diff)
SL-18008 Add Save and Edit buttons to right click menu for materials
-rw-r--r--indra/newview/llmaterialeditor.cpp44
-rw-r--r--indra/newview/llmaterialeditor.h4
-rw-r--r--indra/newview/llviewermenu.cpp159
-rw-r--r--indra/newview/llviewermenu.h4
-rw-r--r--indra/newview/skins/default/xui/en/menu_object.xml16
5 files changed, 199 insertions, 28 deletions
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index c23f9ec4e7..80a0583fd0 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1401,6 +1401,16 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind
}
}
+void LLMaterialEditor::loadLiveMaterial(LLGLTFMaterial * material, bool make_copy)
+{
+ if (!material)
+ {
+ return;
+ }
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
+ me->loadMaterial(material, make_copy);
+}
+
void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index)
{
if (model_in.materials.size() <= index)
@@ -1505,6 +1515,40 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::
applyToSelection();
}
+void LLMaterialEditor::loadMaterial(LLGLTFMaterial * material, bool make_copy)
+{
+ setBaseColorId(material->mBaseColorId);
+ setMetallicRoughnessId(material->mMetallicRoughnessId);
+ setEmissiveId(material->mEmissiveId);
+ setNormalId(material->mNormalId);
+
+ setAlphaMode(material->getAlphaMode());
+ setAlphaCutoff(material->mAlphaCutoff);
+
+ setBaseColor(material->mBaseColor);
+ setEmissiveColor(material->mEmissiveColor);
+
+ setMetalnessFactor(material->mMetallicFactor);
+ setRoughnessFactor(material->mRoughnessFactor);
+
+ setDoubleSided(material->mDoubleSided);
+
+ if (make_copy)
+ {
+ setTitle(LLTrans::getString("New Material"));
+ }
+ // else ??? Think of a name for live editing
+
+ // Todo: At the moment it always makes a 'copy'
+ // Will need a way to expand existing material
+ // once overrides are done
+
+ setHasUnsavedChanges(make_copy);
+
+ openFloater();
+ setFocus(TRUE);
+}
+
bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures)
{
if (model.materials.size() > index)
diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h
index 96bf8cc7a2..3dabc6e26a 100644
--- a/indra/newview/llmaterialeditor.h
+++ b/indra/newview/llmaterialeditor.h
@@ -104,6 +104,7 @@ public:
// @index if -1 and file contains more than one material,
// will promt to select specific one
static void loadMaterialFromFile(const std::string& filename, S32 index = -1);
+ static void loadLiveMaterial(LLGLTFMaterial * material, bool make_copy);
static void onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status);
@@ -221,6 +222,9 @@ public:
private:
void loadMaterial(const tinygltf::Model &model, const std::string &filename_lc, S32 index);
+ // if make_copy is set, will make a copy for saving,
+ // otherwise will edit existing material
+ void loadMaterial(LLGLTFMaterial * material, bool make_copy);
friend class LLMaterialFilePicker;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 31c629fae8..8a92d9062f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -92,6 +92,7 @@
#include "llpanelblockedlist.h"
#include "llpanelmaininventory.h"
#include "llmarketplacefunctions.h"
+#include "llmaterialeditor.h"
#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llmoveview.h"
#include "llnavigationbar.h"
@@ -2781,6 +2782,50 @@ void handle_object_open()
LLFloaterReg::showInstance("openobject");
}
+bool enable_object_edit_gltf_material()
+{
+ struct LLSelectedTEGetmatId : public LLSelectedTEGetFunctor<LLUUID>
+ {
+ LLSelectedTEGetmatId() : mCanModify(true) {}
+ LLUUID get(LLViewerObject* object, S32 te_index)
+ {
+ mCanModify &= (bool)object->permModify();
+ // Todo: probabnly should compare material
+ // pointers instead
+ return object->getRenderMaterialID(te_index);
+ }
+ bool mCanModify;
+ } func;
+ LLUUID mat_id;
+ bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat_id);
+ LL_INFOS() << " Placeholder " << identical << " " << mat_id << LL_ENDL;
+ // Todo: this is a placeholder for overrides,
+ // it will have to make sure all selection is identical
+ return func.mCanModify;
+}
+
+bool enable_object_save_gltf_material()
+{
+ struct LLSelectedTEGetmatId : public LLSelectedTEGetFunctor<LLUUID>
+ {
+ LLSelectedTEGetmatId() : mCanCopy(true) {}
+ LLUUID get(LLViewerObject* object, S32 te_index)
+ {
+ mCanCopy &= (bool)object->permCopy();
+ // permTransfer probably should be passed to editor instead
+ mCanCopy &= (bool)object->permTransfer();
+ return object->getRenderMaterialID(te_index);
+ }
+ bool mCanCopy;
+ } func;
+ LLUUID mat_id;
+ bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat_id);
+ LL_INFOS() << " Placeholder " << identical << " " << mat_id << LL_ENDL;
+ // Todo: this is a placeholder for overrides,
+ // it will have to make sure all selection is identical
+ return func.mCanCopy;
+}
+
bool enable_object_open()
{
// Look for contents in root object, which is all the LLFloaterOpenObject
@@ -2846,37 +2891,42 @@ class LLObjectBuild : public view_listener_t
}
};
-void handle_object_edit()
+void update_camera()
{
- LLViewerParcelMgr::getInstance()->deselectLand();
+ LLViewerParcelMgr::getInstance()->deselectLand();
- if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
- {
- LLFloaterTools::sPreviousFocusOnAvatar = true;
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
+ {
+ LLFloaterTools::sPreviousFocusOnAvatar = true;
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
+ {
+ // always freeze camera in space, even if camera doesn't move
+ // so, for example, follow cam scripts can't affect you when in build mode
+ gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ }
+ else
+ {
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ LLViewerObject* selected_objectp = selection->getFirstRootObject();
+ if (selected_objectp)
+ {
+ // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
+ gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
+ gAgentCamera.cameraZoomIn(0.666f);
+ gAgentCamera.cameraOrbitOver(30.f * DEG_TO_RAD);
+ gViewerWindow->moveCursorToCenter();
+ }
+ }
+ }
+}
+
+void handle_object_edit()
+{
+ update_camera();
- if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
- {
- // always freeze camera in space, even if camera doesn't move
- // so, for example, follow cam scripts can't affect you when in build mode
- gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- }
- else
- {
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- LLViewerObject* selected_objectp = selection->getFirstRootObject();
- if (selected_objectp)
- {
- // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
- gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
- gAgentCamera.cameraZoomIn(0.666f);
- gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
- gViewerWindow->moveCursorToCenter();
- }
- }
- }
-
LLFloaterReg::showInstance("build");
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
@@ -2890,6 +2940,54 @@ void handle_object_edit()
return;
}
+void load_life_gltf_material(bool copy)
+{
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ // All materials are supposed to be identical, so pcik any node
+ LLViewerObject* object = selection->getFirstNode()->getObject();
+ if (!object)
+ {
+ return;
+ }
+
+ // This functionality is a plcaholder for overrides
+ // so id doesn't load object by id, but instead gets material directly
+ LLGLTFMaterial * mat = NULL;
+
+ const S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); // avatars have TEs but no faces
+ for (S32 face = 0; face < num_tes; ++face)
+ {
+ LLTextureEntry *te = object->getTE(face);
+ if (te->isSelected())
+ {
+ mat = te->getGLTFMaterial();
+ break;
+ }
+ }
+
+ if (mat == NULL)
+ {
+ return;
+ }
+
+ update_camera();
+
+ LLMaterialEditor::loadLiveMaterial(mat, copy);
+
+ LLViewerJoystick::getInstance()->moveObjects(true);
+ LLViewerJoystick::getInstance()->setNeedsReset(true);
+}
+
+void handle_object_edit_gltf_material()
+{
+ load_life_gltf_material(false);
+}
+
+void handle_object_save_gltf_material()
+{
+ load_life_gltf_material(true);
+}
+
void handle_attachment_edit(const LLUUID& inv_item_id)
{
if (isAgentAvatarValid())
@@ -9560,10 +9658,15 @@ void initialize_menus()
commit.add("Object.Buy", boost::bind(&handle_buy));
commit.add("Object.Edit", boost::bind(&handle_object_edit));
+ commit.add("Object.Edit", boost::bind(&handle_object_edit));
+ commit.add("Object.EditGLTFMaterial", boost::bind(&handle_object_edit_gltf_material));
+ commit.add("Object.SaveGLTFMaterial", boost::bind(&handle_object_save_gltf_material));
commit.add("Object.Inspect", boost::bind(&handle_object_inspect));
commit.add("Object.Open", boost::bind(&handle_object_open));
commit.add("Object.Take", boost::bind(&handle_take));
commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector));
+ enable.add("Object.EnableEditGLTFMaterial", boost::bind(&enable_object_edit_gltf_material));
+ enable.add("Object.EnableSaveGLTFMaterial", boost::bind(&enable_object_save_gltf_material));
enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index a90b32c984..0673652e61 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -90,6 +90,8 @@ void handle_gestures(void*);
void handle_sit_down(void*);
void handle_object_build(void*);
void handle_object_touch();
+bool enable_object_edit_gltf_material();
+bool enable_object_save_gltf_material();
bool enable_object_open();
void handle_object_open();
@@ -108,6 +110,8 @@ void handle_zoom_to_object(LLUUID object_id);
void handle_object_return();
void handle_object_delete();
void handle_object_edit();
+void handle_object_edit_gltf_material();
+void handle_object_save_gltf_material();
void handle_attachment_edit(const LLUUID& inv_item_id);
void handle_attachment_touch(const LLUUID& inv_item_id);
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index ce34508303..6d37c15815 100644
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -22,6 +22,22 @@
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
label="Build"
name="Build">
<menu_item_call.on_click