summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llinventorybridge.cpp3
-rw-r--r--indra/newview/llmaterialeditor.cpp207
-rw-r--r--indra/newview/llmaterialeditor.h58
-rw-r--r--indra/newview/llviewerfloaterreg.cpp3
-rw-r--r--indra/newview/llviewerinventory.cpp11
-rw-r--r--indra/newview/skins/default/xui/en/floater_material_editor.xml374
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml10
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml1
11 files changed, 684 insertions, 1 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e7aa884f6b..0d2b99a8cd 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -404,6 +404,7 @@ set(viewer_SOURCE_FILES
llmaniptranslate.cpp
llmarketplacefunctions.cpp
llmarketplacenotifications.cpp
+ llmaterialeditor.cpp
llmaterialmgr.cpp
llmediactrl.cpp
llmediadataclient.cpp
@@ -1044,6 +1045,7 @@ set(viewer_HEADER_FILES
llmaniptranslate.h
llmarketplacefunctions.h
llmarketplacenotifications.h
+ llmaterialeditor.h
llmaterialmgr.h
llmediactrl.h
llmediadataclient.h
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a0de3a2af1..a296d2dfef 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4011,6 +4011,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Note"));
disabled_items.push_back(std::string("New Settings"));
disabled_items.push_back(std::string("New Gesture"));
+ disabled_items.push_back(std::string("New Material"));
disabled_items.push_back(std::string("New Clothes"));
disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
@@ -4038,6 +4039,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Script"));
disabled_items.push_back(std::string("New Note"));
disabled_items.push_back(std::string("New Gesture"));
+ disabled_items.push_back(std::string("New Material"));
disabled_items.push_back(std::string("New Clothes"));
disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
@@ -4102,6 +4104,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
items.push_back(std::string("New Script"));
items.push_back(std::string("New Note"));
items.push_back(std::string("New Gesture"));
+ items.push_back(std::string("New Material"));
items.push_back(std::string("New Clothes"));
items.push_back(std::string("New Body Parts"));
items.push_back(std::string("New Settings"));
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
new file mode 100644
index 0000000000..6e7f7adfed
--- /dev/null
+++ b/indra/newview/llmaterialeditor.cpp
@@ -0,0 +1,207 @@
+/**
+ * @file llmaterialeditor.cpp
+ * @brief Implementation of the notecard editor
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llmaterialeditor.h"
+#include "llcombobox.h"
+
+#include "tinygltf/tiny_gltf.h"
+
+///----------------------------------------------------------------------------
+/// Class LLPreviewNotecard
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLMaterialEditor::LLMaterialEditor(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+BOOL LLMaterialEditor::postBuild()
+{
+ childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this));
+ return LLFloater::postBuild();
+}
+
+LLUUID LLMaterialEditor::getAlbedoId()
+{
+ return childGetValue("albedo texture").asUUID();
+}
+
+LLColor4 LLMaterialEditor::getAlbedoColor()
+{
+ LLColor4 ret = LLColor4(childGetValue("albedo color"));
+ ret.mV[3] = getTransparency();
+ return ret;
+}
+
+
+F32 LLMaterialEditor::getTransparency()
+{
+ return childGetValue("transparency").asReal();
+}
+
+std::string LLMaterialEditor::getAlphaMode()
+{
+ return childGetValue("alpha mode").asString();
+}
+
+F32 LLMaterialEditor::getAlphaCutoff()
+{
+ return childGetValue("alpha cutoff").asReal();
+}
+
+LLUUID LLMaterialEditor::getMetallicRoughnessId()
+{
+ return childGetValue("metallic-roughness texture").asUUID();
+}
+
+F32 LLMaterialEditor::getMetalnessFactor()
+{
+ return childGetValue("metalness factor").asReal();
+}
+
+F32 LLMaterialEditor::getRoughnessFactor()
+{
+ return childGetValue("roughness factor").asReal();
+}
+
+LLUUID LLMaterialEditor::getEmissiveId()
+{
+ return childGetValue("emissive texture").asUUID();
+}
+
+LLColor4 LLMaterialEditor::getEmissiveColor()
+{
+ return LLColor4(childGetValue("emissive color"));
+}
+
+LLUUID LLMaterialEditor::getNormalId()
+{
+ return childGetValue("normal texture").asUUID();
+}
+
+bool LLMaterialEditor::getDoubleSided()
+{
+ return childGetValue("double sided").asBoolean();
+}
+
+
+static void write_color(const LLColor4& color, std::vector<double>& c)
+{
+ for (int i = 0; i < c.size(); ++i) // NOTE -- use c.size because some gltf colors are 3-component
+ {
+ c[i] = color.mV[i];
+ }
+}
+
+static U32 write_texture(const LLUUID& id, tinygltf::Model& model)
+{
+ tinygltf::Image image;
+ image.uri = id.asString();
+ model.images.push_back(image);
+ U32 image_idx = model.images.size() - 1;
+
+ tinygltf::Texture texture;
+ texture.source = image_idx;
+ model.textures.push_back(texture);
+ U32 texture_idx = model.textures.size() - 1;
+
+ return texture_idx;
+}
+
+void LLMaterialEditor::onClickSave()
+{
+ tinygltf::Model model;
+ model.materials.resize(1);
+ tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness;
+
+ // write albedo
+ LLColor4 albedo_color = getAlbedoColor();
+ albedo_color.mV[3] = getTransparency();
+ write_color(albedo_color, pbrMaterial.baseColorFactor);
+
+ model.materials[0].alphaCutoff = getAlphaCutoff();
+ model.materials[0].alphaMode = getAlphaMode();
+
+ LLUUID albedo_id = getAlbedoId();
+
+ if (albedo_id.notNull())
+ {
+ U32 texture_idx = write_texture(albedo_id, model);
+
+ pbrMaterial.baseColorTexture.index = texture_idx;
+ }
+
+ // write metallic/roughness
+ F32 metalness = getMetalnessFactor();
+ F32 roughness = getRoughnessFactor();
+
+ pbrMaterial.metallicFactor = metalness;
+ pbrMaterial.roughnessFactor = roughness;
+
+ LLUUID mr_id = getMetallicRoughnessId();
+ if (mr_id.notNull())
+ {
+ U32 texture_idx = write_texture(mr_id, model);
+ pbrMaterial.metallicRoughnessTexture.index = texture_idx;
+ }
+
+ //write emissive
+ LLColor4 emissive_color = getEmissiveColor();
+ model.materials[0].emissiveFactor.resize(3);
+ write_color(emissive_color, model.materials[0].emissiveFactor);
+
+ LLUUID emissive_id = getEmissiveId();
+ if (emissive_id.notNull())
+ {
+ U32 idx = write_texture(emissive_id, model);
+ model.materials[0].emissiveTexture.index = idx;
+ }
+
+ //write normal
+ LLUUID normal_id = getNormalId();
+ if (normal_id.notNull())
+ {
+ U32 idx = write_texture(normal_id, model);
+ model.materials[0].normalTexture.index = idx;
+ }
+
+ //write doublesided
+ model.materials[0].doubleSided = getDoubleSided();
+
+ std::ostringstream str;
+
+ tinygltf::TinyGLTF gltf;
+ model.asset.version = "2.0";
+ gltf.WriteGltfSceneToStream(&model, str, true, false);
+
+ std::string dump = str.str();
+
+ LL_INFOS() << dump << LL_ENDL;
+}
+
diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h
new file mode 100644
index 0000000000..febdb3bbc1
--- /dev/null
+++ b/indra/newview/llmaterialeditor.h
@@ -0,0 +1,58 @@
+/**
+ * @file llmaterialeditor.h
+ * @brief LLMaterialEditor class header file
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "llfloater.h"
+
+class LLMaterialEditor : public LLFloater
+{
+public:
+ LLMaterialEditor(const LLSD& key);
+
+ void onClickSave();
+
+ // llpanel
+ BOOL postBuild() override;
+
+ LLUUID getAlbedoId();
+ LLColor4 getAlbedoColor();
+ F32 getTransparency();
+ std::string getAlphaMode();
+ F32 getAlphaCutoff();
+
+ LLUUID getMetallicRoughnessId();
+ F32 getMetalnessFactor();
+ F32 getRoughnessFactor();
+
+ LLUUID getEmissiveId();
+ LLColor4 getEmissiveColor();
+
+ LLUUID getNormalId();
+
+ bool getDoubleSided();
+};
+
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index dd03d6cfdd..97cb8e2000 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -152,6 +152,7 @@
#include "llinspectobject.h"
#include "llinspectremoteobject.h"
#include "llinspecttoast.h"
+#include "llmaterialeditor.h"
#include "llmoveview.h"
#include "llfloaterimnearbychat.h"
#include "llpanelblockedlist.h"
@@ -337,6 +338,8 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("save_camera_preset", "floater_save_camera_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSaveCameraPreset>);
LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);
+ LLFloaterReg::add("material_editor", "floater_material_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLMaterialEditor>);
+
LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
LLFloaterReg::add("test_inspectors", "floater_test_inspectors.xml", &LLFloaterReg::build<LLFloaterTestInspectors>);
//LLFloaterReg::add("test_list_view", "floater_test_list_view.xml",&LLFloaterReg::build<LLFloaterTestListView>);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 55ac817479..d777cde554 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -147,6 +147,7 @@ LLLocalizedInventoryItemsDictionary::LLLocalizedInventoryItemsDictionary()
mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable");
mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture");
+ mInventoryItemsDict["New Material"] = LLTrans::getString("New Material");
mInventoryItemsDict["New Script"] = LLTrans::getString("New Script");
mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder");
mInventoryItemsDict["New Note"] = LLTrans::getString("New Note");
@@ -1672,6 +1673,7 @@ void remove_folder_contents(const LLUUID& category, bool keep_outfit_links,
const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
+const std::string NEW_MATERIAL_NAME = "New Material"; // *TODO:Translate? (probably not)
// ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
@@ -1727,6 +1729,15 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
LLInventoryType::IT_GESTURE,
PERM_ALL); // overridden in create_new_item
}
+ else if ("material" == type_name)
+ {
+ const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
+ create_new_item(NEW_GESTURE_NAME,
+ parent_id,
+ LLAssetType::AT_MATERIAL,
+ LLInventoryType::IT_MATERIAL,
+ PERM_ALL); // overridden in create_new_item
+ }
else if (("sky" == type_name) || ("water" == type_name) || ("daycycle" == type_name))
{
LLSettingsType::type_e stype(LLSettingsType::ST_NONE);
diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml
new file mode 100644
index 0000000000..5d72e6f79d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="false"
+ default_tab_group="1"
+ height="777"
+ layout="topleft"
+ name="material editor"
+ help_topic="material_editor"
+ title="Material: [MATERIAL_NAME]"
+ width="256">
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="196"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="Texture"
+ top="20"
+ >
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="64">
+ Albedo:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="albedo texture"
+ tool_tip="Albedo map. Alpha channel is optional and used for transparency."
+ width="128" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top_delta="-15"
+ >
+ Tint
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="albedo color"
+ width="40" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ >
+ Transparency
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ max_val="1"
+ name="transparency"
+ width="64"
+ />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label alphamode"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="5"
+ width="90">
+ Alpha mode
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="alpha mode"
+ top_pad="4"
+ width="96">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="OPAQUE" />
+ <combo_box.item
+ label="Alpha blending"
+ name="Alpha blending"
+ value="BLEND" />
+ <combo_box.item
+ label="Alpha masking"
+ name="Alpha masking"
+ value="MASK" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ >
+ Alpha Cutoff
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ max_val="1"
+ name="alpha cutoff"
+ width="64"
+ />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="160"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="Texture"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top_pad="5"
+ >
+ Metallic-Roughness:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ width="128"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="metallic-roughness texture"
+ tool_tip="GLTF metallic-roughness map with optional occlusion. Red channel is occlusion, green channel is roughness, blue channel is metalness."
+ top_pad="8"
+ />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top_delta="-15"
+ >
+ Metallic Factor
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ max_val="100"
+ name="metalness factor"
+ width="64"
+ />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ >
+ Roughness Factor
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ max_val="100"
+ name="roughness factor"
+ width="64"
+ />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="160"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="Texture"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="64">
+ Emissive:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="emissive texture"
+ width="128" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top_delta="-15"
+ >
+ Tint
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="emissive color"
+ width="40" />
+ <!--<text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="64"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ >
+ Intensity
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ max_val="100"
+ width="64"
+ />-->
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="160"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="64">
+ Normal:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="normal texture"
+ width="128" />
+ <!--<check_box
+ follows="left|top"
+ label="Mikkt Space"
+ left_pad="10"
+ top_delta="0"
+ height="25"
+ width="120" />-->
+ </panel>
+ <check_box
+ follows="left|top"
+ label="Double Sided"
+ left="5"
+ top_pad="5"
+ name="double sided"
+ height="25"
+ width="120" />
+ <button
+ follows="right|bottom"
+ height="25"
+ label="Save"
+ layout="bottomright"
+ name="save"
+ tool_tip="Browse for an editor (executable) to edit floater XML files"
+ top_delta="-2"
+ left="5"
+ width="246" />
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 78ca170813..60a177f0bd 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -183,6 +183,14 @@
function="Inventory.DoCreate"
parameter="gesture" />
</menu_item_call>
+ <menu_item_call
+ label="New Material"
+ layout="topleft"
+ name="New Material">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="material" />
+ </menu_item_call>
<menu
label="New Clothes"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 3385a29a6c..0e193521a3 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -97,6 +97,14 @@
function="Inventory.DoCreate"
parameter="gesture" />
</menu_item_call>
+ <menu_item_call
+ label="New Material"
+ layout="topleft"
+ name="New Material">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="material" />
+ </menu_item_call>
<menu
height="175"
label="New Clothes"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 7a5c2099eb..623d0d88eb 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1595,7 +1595,15 @@ function="World.EnvPreset"
parameter="" />
</menu_item_call>
</menu>
- <menu_item_separator/>
+ <menu_item_call
+ label="Material Editor"
+ name="material_editor_menu_item">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="material_editor" />
+ </menu_item_call>
+
+ <menu_item_separator/>
<menu_item_call
enabled="false"
label="Undo"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index acb3a720b9..0866f29355 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3835,6 +3835,7 @@ Abuse Report</string>
<string name="New Physics">New Physics</string>
<string name="Invalid Wearable">Invalid Wearable</string>
<string name="New Gesture">New Gesture</string>
+ <string name="New Material">New Material</string>
<string name="New Script">New Script</string>
<string name="New Note">New Note</string>
<string name="New Folder">New Folder</string>