SL-17586 WIP -- LLMaterialEditor prototype and "New Material" inventory buttons.

master
Dave Parks 2022-06-14 23:39:11 -05:00
parent 929abcd296
commit ad533fcd6b
11 changed files with 684 additions and 1 deletions

View File

@ -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

View File

@ -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"));

View File

@ -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;
}

View File

@ -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();
};

View File

@ -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>);

View File

@ -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);

View File

@ -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>

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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>