[Project Copy/Paste] Texture support

meow-7.2.2
Kadah_Coba 2019-10-14 20:35:44 -07:00
parent ce48cb4303
commit 1e1707d532
4 changed files with 618 additions and 16 deletions

View File

@ -38,6 +38,7 @@
#include "llfontgl.h"
// project includes
#include "llagent.h" // gAgent
#include "llagentdata.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
@ -45,10 +46,14 @@
#include "llcombobox.h"
#include "lldrawpoolbump.h"
#include "llface.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h" // gInventory
#include "lllineeditor.h"
#include "llmaterialmgr.h"
#include "llmediaentry.h"
#include "llmenubutton.h"
#include "llnotificationsutil.h"
#include "llpanelobject.h" // LLPanelObject::canCopyTexture
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@ -295,7 +300,18 @@ BOOL LLPanelFace::postBuild()
{
mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
}
mBtnCopyFaces = getChild<LLButton>("copy_face_btn");
if(mBtnCopyFaces)
{
BtnCopyFaces->setCommitCallback(boost::bind(&LLPanelFace::onCopyFaces, this));
}
mBtnPasteFaces = getChild<LLButton>("paste_face_btn");
if (mBtnPasteFaces)
{
mBtnPasteFaces->setCommitCallback(boost::bind(&LLPanelFace::onPasteFaces, this));
}
mBtnPasteMenu = getChild<LLMenuButton>("paste_face_gear_btn");
clearCtrls();
@ -304,9 +320,21 @@ BOOL LLPanelFace::postBuild()
LLPanelFace::LLPanelFace()
: LLPanel(),
mIsAlpha(false)
mIsAlpha(false),
mPasteColor(TRUE),
mPasteAlpha(TRUE),
mPasteGlow(TRUE),
mPasteDiffuse(TRUE),
mPasteNormal(TRUE),
mPasteSpecular(TRUE),
mPasteMapping(TRUE),
mPasteMedia(TRUE)
{
USE_TEXTURE = LLTrans::getString("use_texture");
mEnableCallbackRegistrar.add("BuildFace.PasteCheckItem", boost::bind(&LLPanelFace::pasteCheckMenuItem, this, _2));
mCommitCallbackRegistrar.add("BuildFace.PasteDoToSelected", boost::bind(&LLPanelFace::pasteDoMenuItem, this, _2));
mEnableCallbackRegistrar.add("BuildFace.PasteEnable", boost::bind(&LLPanelFace::pasteEnabletMenuItem, this, _2));
}
@ -1407,6 +1435,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
}
S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
BOOL single_volume = (selected_count == 1);
mBtnCopyFaces->setEnabled(editable && single_volume);
mBtnPasteFaces->setEnabled(editable && (mClipboard.size() > 0));
mBtnPasteMenu->setEnabled(editable);
// Set variable values for numeric expressions
LLCalc* calcp = LLCalc::getInstance();
calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal());
@ -1602,8 +1636,6 @@ void LLPanelFace::updateVisibility()
getChildView("bumpyRot")->setVisible(show_bumpiness);
getChildView("bumpyOffsetU")->setVisible(show_bumpiness);
getChildView("bumpyOffsetV")->setVisible(show_bumpiness);
}
// static
@ -2681,3 +2713,445 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic
} max_diff_repeats_func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );
}
static LLSD texture_clipboard;
void LLPanelFace::onCopyFaces()
{
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
if( !objectp || !node
|| objectp->getPCode() != LL_PCODE_VOLUME
|| !objectp->permModify()
|| objectp->isPermanentEnforced()
|| selected_count > 1)
{
return;
}
mClipboard.clear();
S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
for (S32 te = 0; te < num_tes; ++te)
{
if (node->isTESelected(te))
{
LLTextureEntry* tep = objectp->getTE(te);
if (tep)
{
LLSD te_data;
te_data["te"] = tep->asLLSD();
te_data["te"]["glow"] = tep->getGlow();
te_data["te"]["shiny"] = tep->getShiny();
if (te_data["te"].has("imageid"))
{
LLUUID id = te_data["te"]["imageid"].asUUID();
if (id.isNull() || !LLPanelObject::canCopyTexture(id))
{
te_data["te"].erase("imageid");
te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" ));
}
// else
// {
// te_data["te"]["imageid"] = canCopyTexture(te_data["te"]["imageid"].asUUID());
// }
}
LLMaterialPtr material_ptr = tep->getMaterialParams();
if (!material_ptr.isNull())
{
LLSD mat_data;
mat_data["NormMap"] = material_ptr->getNormalID();
mat_data["SpecMap"] = material_ptr->getSpecularID();
mat_data["NormRepX"] = material_ptr->getNormalRepeatX();
mat_data["NormRepY"] = material_ptr->getNormalRepeatY();
mat_data["NormOffX"] = material_ptr->getNormalOffsetX();
mat_data["NormOffY"] = material_ptr->getNormalOffsetY();
mat_data["NormRot"] = material_ptr->getNormalRotation();
mat_data["SpecRepX"] = material_ptr->getSpecularRepeatX();
mat_data["SpecRepY"] = material_ptr->getSpecularRepeatY();
mat_data["SpecOffX"] = material_ptr->getSpecularOffsetX();
mat_data["SpecOffY"] = material_ptr->getSpecularOffsetY();
mat_data["SpecRot"] = material_ptr->getSpecularRotation();
mat_data["SpecColor"] = material_ptr->getSpecularLightColor().getValue();
mat_data["SpecExp"] = material_ptr->getSpecularLightExponent();
mat_data["EnvIntensity"] = material_ptr->getEnvironmentIntensity();
mat_data["AlphaMaskCutoff"] = material_ptr->getAlphaMaskCutoff();
mat_data["DiffuseAlphaMode"] = material_ptr->getDiffuseAlphaMode();
// Replace no-copy textures, destination texture will get used instead if available
if (mat_data.has("NormMap"))
{
LLUUID id = te_data["material"]["NormMap"].asUUID();
if (id.notNull() && !LLPanelObject::canCopyTexture(id))
{
mat_data["NormMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" ));
mat_data["NormMapNoCopy"] = true;
}
}
if (mat_data.has("SpecMap"))
{
LLUUID id = te_data["material"]["SpecMap"].asUUID();
if (id.notNull() && !LLPanelObject::canCopyTexture(id))
{
mat_data["SpecMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" ));
mat_data["SpecMapNoCopy"] = true;
}
}
te_data["material"] = mat_data;
}
//*TODO: Media
mClipboard.append(te_data);
}
}
}
}
void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te)
{
LLSD te_data;
if (mClipboard.size() == 1)
{
te_data = *(mClipboard.beginArray());
}
else if (mClipboard[te])
{
te_data = mClipboard[te];
}
else
{
return;
}
LLTextureEntry* tep = objectp->getTE(te);
if (tep)
{
if (te_data.has("te"))
{
// Texture
if (mPasteDiffuse)
{
// Replace no-copy texture with target's
if (!te_data["te"].has("imageid"))
{
te_data["te"]["imageid"] = tep->getID();
}
const LLUUID& imageid = te_data["te"]["imageid"].asUUID();
LLViewerInventoryItem* item = gInventory.getItem(imageid);
if (item)
{
if (te == -1) // all faces
{
LLToolDragAndDrop::dropTextureAllFaces(objectp,
item,
LLToolDragAndDrop::SOURCE_AGENT,
LLUUID::null);
}
else // one face
{
LLToolDragAndDrop::dropTextureOneFace(objectp,
te,
item,
LLToolDragAndDrop::SOURCE_AGENT,
LLUUID::null);
}
}
else // not an inventory item
{
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
objectp->setTEImage(U8(te), image);
}
}
// Color / Alpha
if ((mPasteColor || mPasteAlpha) && te_data.has("colors"))
{
LLColor4 color = objectp->getTE(te)->getColor();
LLColor4 clip_color;
clip_color.setValue(te_data["colors"]);
// Color
if (mPasteColor)
{
color.mV[VRED] = clip_color.mV[VRED];
color.mV[VGREEN] = clip_color.mV[VGREEN];
color.mV[VBLUE] = clip_color.mV[VBLUE];
}
// Alpha
if (mPasteAlpha)
{
color.mV[VALPHA] = clip_color.mV[VALPHA];
}
objectp->setTEColor(te, color);
}
// Glow
if (mPasteGlow && te_data.has("glow"))
{
objectp->setTEGlow(te, (F32)te_data["glow"].asReal());
}
// Texture map
if (mPasteMapping)
{
if (te_data.has("scales") && te_data.has("scalet"))
{
objectp->setTEScale(te, (F32)te_data["scales"].asReal(), (F32)te_data["scalet"].asReal());
}
if (te_data.has("offsets") && te_data.has("offsett"))
{
objectp->setTEOffset(te, (F32)te_data["offsets"].asReal(), (F32)te_data["offsett"].asReal());
}
if (te_data.has("imagerot"))
{
objectp->setTERotation(te, (F32)te_data["imagerot"].asReal());
}
}
// Media
if (mPasteMedia && te_data.has("media"))
{
//*TODO
}
else
{
// // Keep media flags on destination unchanged
// // Media is handled later
// if (te_data["te"].has("media_flags"))
// {
// te_data["te"]["media_flags"] = tep->getMediaTexGen();
// }
}
}
if (te_data.has("material"))
{
LLUUID object_id = objectp->getID();
LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
if (mPasteNormal)
{
// Replace placeholders with target's
if (te_data["material"].has("NormMapNoCopy"))
{
LLMaterialPtr material = tep->getMaterialParams();
if (material.notNull())
{
LLUUID id = material->getNormalID();
if (id.notNull())
{
te_data["material"]["NormMap"] = id;
}
}
}
LLSelectedTEMaterial::setNormalID(this, te_data["material"]["NormMap"].asUUID(), te, object_id);
LLSelectedTEMaterial::setNormalRepeatX(this, (F32)te_data["material"]["NormRepX"].asReal(), te, object_id);
LLSelectedTEMaterial::setNormalRepeatY(this, (F32)te_data["material"]["NormRepY"].asReal(), te, object_id);
LLSelectedTEMaterial::setNormalOffsetX(this, (F32)te_data["material"]["NormOffX"].asReal(), te, object_id);
LLSelectedTEMaterial::setNormalOffsetY(this, (F32)te_data["material"]["NormOffY"].asReal(), te, object_id);
LLSelectedTEMaterial::setNormalRotation(this, (F32)te_data["material"]["NormRot"].asReal(), te, object_id);
}
if (mPasteSpecular)
{
// Replace placeholders with target's
if (te_data["material"].has("SpecMapNoCopy"))
{
LLMaterialPtr material = tep->getMaterialParams();
if (material.notNull())
{
LLUUID id = material->getSpecularID();
if (id.notNull())
{
te_data["material"]["SpecMap"] = id;
}
}
}
LLSelectedTEMaterial::setSpecularID(this, te_data["material"]["SpecMap"].asUUID(), te, object_id);
LLSelectedTEMaterial::setSpecularRepeatX(this, (F32)te_data["material"]["SpecRepX"].asReal(), te, object_id);
LLSelectedTEMaterial::setSpecularRepeatY(this, (F32)te_data["material"]["SpecRepY"].asReal(), te, object_id);
LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id);
LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id);
LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id);
LLColor4 spec_color(te_data["material"]["SpecColor"]);
LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te);
LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id);
LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te), object_id;
LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
if (te_data.has("shiny"))
{
objectp->setTEShiny(te, (U8)te_data["shiny"].asInteger());
}
}
}
}
}
struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor
{
LLPanelFacePasteTexFunctor(LLPanelFace* panel) :
mPanelFace(panel){}
virtual bool apply(LLViewerObject* objectp, S32 te)
{
mPanelFace->pasteFace(objectp, te);
return true;
}
private:
LLPanelFace *mPanelFace;
};
void LLPanelFace::onPasteFaces()
{
LLPanelFacePasteTexFunctor paste_func(this);
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&paste_func);
LLPanelFaceSendFunctor sendfunc;
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
}
bool LLPanelFace::pasteCheckMenuItem(const LLSD& userdata)
{
std::string command = userdata.asString();
if ("Color" == command)
{
return mPasteColor;
}
if ("Transparency" == command)
{
return mPasteAlpha;
}
if ("Glow" == command)
{
return mPasteGlow;
}
if ("Diffuse" == command)
{
return mPasteDiffuse;
}
if ("Normal" == command)
{
return mPasteNormal;
}
if ("Specular" == command)
{
return mPasteSpecular;
}
if ("Mapping" == command)
{
return mPasteMapping;
}
if ("Media" == command)
{
return mPasteMedia;
}
return false;
}
void LLPanelFace::pasteDoMenuItem(const LLSD& userdata)
{
std::string command = userdata.asString();
if ("Color" == command)
{
mPasteColor = !mPasteColor;
}
if ("Transparency" == command)
{
mPasteAlpha = !mPasteAlpha;
}
if ("Glow" == command)
{
mPasteGlow = !mPasteGlow;
}
if ("Diffuse" == command)
{
mPasteDiffuse = !mPasteDiffuse;
}
if ("Normal" == command)
{
mPasteNormal = !mPasteNormal;
}
if ("Specular" == command)
{
mPasteSpecular = !mPasteSpecular;
}
if ("Mapping" == command)
{
mPasteMapping = !mPasteMapping;
}
if ("Media" == command)
{
mPasteMedia = !mPasteMedia;
}
}
bool LLPanelFace::pasteEnabletMenuItem(const LLSD& userdata)
{
std::string command = userdata.asString();
// Keep at least one option enabled
S32 num_enabled = mPasteColor
+ mPasteAlpha
+ mPasteGlow
+ mPasteDiffuse
+ mPasteNormal
+ mPasteSpecular
+ mPasteMapping
+ mPasteMedia;
if ( num_enabled == 1)
{
if ("Color" == command && mPasteColor)
{
return false;
}
if ("Transparency" == command && mPasteAlpha)
{
return false;
}
if ("Glow" == command && mPasteGlow)
{
return false;
}
if ("Diffuse" == command && mPasteDiffuse)
{
return false;
}
if ("Normal" == command && mPasteNormal)
{
return false;
}
if ("Specular" == command && mPasteSpecular)
{
return false;
}
if ("Mapping" == command && mPasteMapping)
{
return false;
}
if ("Media" == command && mPasteMedia)
{
return false;
}
}
return true;
}

View File

@ -47,6 +47,7 @@ class LLUICtrl;
class LLViewerObject;
class LLFloater;
class LLMaterialID;
class LLMenuButton;
// Represents an edit for use in replicating the op across one or more materials in the selection set.
//
@ -113,6 +114,8 @@ public:
LLRender::eTexIndex getTextureChannelToEdit();
void pasteFace(LLViewerObject* object, S32 te);
protected:
void getState();
@ -203,9 +206,13 @@ protected:
static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
static void onClickAutoFix(void*);
static F32 valueGlow(LLViewerObject* object, S32 face);
void onCopyFaces();
void onPasteFaces();
bool pasteCheckMenuItem(const LLSD& userdata);
void pasteDoMenuItem(const LLSD& userdata);
bool pasteEnabletMenuItem(const LLSD& userdata);
static F32 valueGlow(LLViewerObject* object, S32 face);
private:
@ -232,6 +239,20 @@ private:
F32 getCurrentShinyOffsetU();
F32 getCurrentShinyOffsetV();
LLButton *mBtnCopyFaces;
LLButton *mBtnPasteFaces;
LLMenuButton *mBtnPasteMenu;
LLSD mClipboard;
BOOL mPasteColor;
BOOL mPasteAlpha;
BOOL mPasteGlow;
BOOL mPasteDiffuse;
BOOL mPasteNormal;
BOOL mPasteSpecular;
BOOL mPasteMapping;
BOOL mPasteMedia;
// Update visibility of controls to match current UI mode
// (e.g. materials vs media editing)
//
@ -495,6 +516,8 @@ public:
DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID);
DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID);
DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor);
DEF_EDIT_MAT_STATE(LLSD, const LLSD&, fromLLSD);
};
class LLSelectedTE

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<toggleable_menu
layout="topleft"
name="Conversation Gear Menu">
<menu_item_check
label="Color"
layout="topleft"
name="Color">
<on_check function="BuildFace.PasteCheckItem" parameter="Color" />
<on_click function="BuildFace.PasteDoToSelected" parameter="Color" />
<on_enable function="BuildFace.PasteEnable" parameter="Color" />
</menu_item_check>
<menu_item_check
label="Transparency"
layout="topleft"
name="Transparency">
<on_check function="BuildFace.PasteCheckItem" parameter="Transparency" />
<on_click function="BuildFace.PasteDoToSelected" parameter="Transparency" />
<on_enable function="BuildFace.PasteEnable" parameter="Transparency" />
</menu_item_check>
<menu_item_check
label="Glow"
layout="topleft"
name="Glow">
<on_check function="BuildFace.PasteCheckItem" parameter="Glow" />
<on_click function="BuildFace.PasteDoToSelected" parameter="Glow" />
<on_enable function="BuildFace.PasteEnable" parameter="Glow" />
</menu_item_check>
<menu_item_check
label="Texture"
layout="topleft"
name="Diffuse">
<on_check function="BuildFace.PasteCheckItem" parameter="Diffuse" />
<on_click function="BuildFace.PasteDoToSelected" parameter="Diffuse" />
<on_enable function="BuildFace.PasteEnable" parameter="Diffuse" />
</menu_item_check>
<menu_item_check
label="Bumpiness"
layout="topleft"
name="Normal">
<on_check function="BuildFace.PasteCheckItem" parameter="Normal" />
<on_click function="BuildFace.PasteDoToSelected" parameter="Normal" />
<on_enable function="BuildFace.PasteEnable" parameter="Normal" />
</menu_item_check>
<menu_item_check
label="Shininess"
layout="topleft"
name="Specular">
<on_check function="BuildFace.PasteCheckItem" parameter="Specular" />
<on_click function="BuildFace.PasteDoToSelected" parameter="Specular" />
<on_enable function="BuildFace.PasteEnable" parameter="Specular" />
</menu_item_check>
<menu_item_check
label="Mapping"
layout="topleft"
name="Mapping">
<on_check function="BuildFace.PasteCheckItem" parameter="Mapping" />
<on_click function="BuildFace.PasteDoToSelected" parameter="Mapping" />
<on_enable function="BuildFace.PasteEnable" parameter="Mapping" />
</menu_item_check>
<menu_item_check
label="Media"
layout="topleft"
name="Media">
<on_check function="BuildFace.PasteCheckItem" parameter="Media" />
<on_click function="BuildFace.PasteDoToSelected" parameter="Media" />
<on_enable function="BuildFace.PasteEnable" parameter="Media" />
</menu_item_check>
</toggleable_menu>

View File

@ -43,7 +43,7 @@
follows="left|top"
height="10"
layout="topleft"
left_pad="15"
left_pad="10"
name="color trans"
text_readonly_color="LabelDisabledColor"
top="6"
@ -68,7 +68,7 @@
follows="left|top"
height="10"
layout="topleft"
left_pad="15"
left_pad="13"
name="glow label"
text_readonly_color="LabelDisabledColor"
top="6"
@ -84,7 +84,7 @@
left_delta="0"
name="glow"
top_pad="4"
width="80" />
width="50" />
<check_box
height="19"
label="Full Bright"
@ -93,12 +93,47 @@
name="checkbox fullbright"
top_pad="4"
width="81" />
<button
follows="top|right"
height="23"
label="Copy"
layout="topleft"
left="240"
name="copy_face_btn"
tool_tip="Copy Parameters to Clipboard"
top="6"
width="53">
</button>
<button
follows="top|right"
height="23"
label="Paste"
layout="topleft"
name="paste_face_btn"
tool_tip="Paste Parameters from Clipboard"
top_pad="5"
width="53">
</button>
<menu_button
menu_filename="menu_texture_paste.xml"
follows="top|left"
height="23"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="OptionsMenu_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
left_delta="20"
name="paste_face_gear_btn"
tool_tip="Paste options"
top_pad="5"
width="31"/>
<combo_box
height="23"
layout="topleft"
left="10"
name="combobox matmedia"
top_pad="5"
top="70"
width="100">
<combo_box.item
label="Materials"
@ -113,10 +148,10 @@
control_name="ComboMaterialType"
height="50"
layout="topleft"
left_pad="20"
left_pad="5"
top_delta="-10"
width="150"
visible = "false"
visible = "true"
name="radio_material_type">
<radio_item
label="Texture (diffuse)"
@ -139,7 +174,7 @@
layout="topleft"
top_pad="1"
value="2"/>
</radio_group>
</radio_group>
<check_box
control_name="SyncMaterialSettings"
follows="top|left"
@ -158,7 +193,7 @@
fallback_image="materials_ui_x_24.png"
follows="left|top"
height="80"
label="Texture "
label="Texture"
layout="topleft"
left="10"
name="texture control"
@ -235,7 +270,7 @@
fallback_image="materials_ui_x_24.png"
follows="left|top"
height="80"
label="Texture "
label="Texture"
layout="topleft"
left="10"
name="bumpytexture control"
@ -349,7 +384,7 @@
fallback_image="materials_ui_x_24.png"
follows="left|top"
height="80"
label="Texture "
label="Texture"
layout="topleft"
left="10"
name="shinytexture control"