Gets rid of all those pointless callbacks and static workarounds for legacy callback system. Should massively improve FPS while build floater is open Fixes getChild UI Warnings Removes dumb func
2506 lines
77 KiB
C++
2506 lines
77 KiB
C++
/**
|
|
* @file llpanelface.cpp
|
|
* @brief Panel in the tools floater for editing face textures, colors, etc.
|
|
*
|
|
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
|
*
|
|
* Copyright (c) 2001-2009, Linden Research, Inc.
|
|
*
|
|
* Second Life Viewer Source Code
|
|
* The source code in this file ("Source Code") is provided by Linden Lab
|
|
* to you under the terms of the GNU General Public License, version 2.0
|
|
* ("GPL"), unless you have obtained a separate licensing agreement
|
|
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
|
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
|
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
|
*
|
|
* There are special exceptions to the terms and conditions of the GPL as
|
|
* it is applied to this Source Code. View the full text of the exception
|
|
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
|
* online at
|
|
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
*
|
|
* By copying, modifying or distributing this software, you acknowledge
|
|
* that you have read and understood your obligations described above,
|
|
* and agree to abide by those obligations.
|
|
*
|
|
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
|
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
|
* COMPLETENESS OR PERFORMANCE.
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
// file include
|
|
#include "llpanelface.h"
|
|
|
|
// library includes
|
|
#include "llcalc.h"
|
|
#include "llerror.h"
|
|
#include "llfocusmgr.h"
|
|
#include "llrect.h"
|
|
#include "llstring.h"
|
|
#include "llfontgl.h"
|
|
|
|
// project includes
|
|
#include "llagent.h"
|
|
#include "llbutton.h"
|
|
#include "llcheckboxctrl.h"
|
|
#include "llcolorswatch.h"
|
|
#include "llcombobox.h"
|
|
#include "lldrawpoolbump.h"
|
|
#include "llface.h"
|
|
#include "llinventorymodel.h" //Perms check for texture params
|
|
#include "lllineeditor.h"
|
|
#include "llmaterialmgr.h"
|
|
#include "llmediaentry.h"
|
|
#include "llnotificationsutil.h"
|
|
#include "llresmgr.h"
|
|
#include "llselectmgr.h"
|
|
#include "llspinctrl.h"
|
|
#include "lltextbox.h"
|
|
#include "lltexturectrl.h"
|
|
#include "lltextureentry.h"
|
|
#include "lltooldraganddrop.h"
|
|
#include "lltrans.h"
|
|
#include "llui.h"
|
|
#include "llviewercontrol.h"
|
|
#include "llviewermedia.h"
|
|
#include "llviewerobject.h"
|
|
#include "llviewerregion.h"
|
|
#include "llviewerstats.h"
|
|
#include "llvovolume.h"
|
|
#include "lluictrlfactory.h"
|
|
#include "llpluginclassmedia.h"
|
|
#include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
|
|
|
|
//
|
|
// Constant definitions for comboboxes
|
|
// Must match the commbobox definitions in panel_tools_texture.xml
|
|
//
|
|
const S32 MATMEDIA_MATERIAL = 0; // Material
|
|
const S32 MATMEDIA_MEDIA = 1; // Media
|
|
const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture
|
|
const S32 MATTYPE_NORMAL = 1; // Normal map
|
|
const S32 MATTYPE_SPECULAR = 2; // Specular map
|
|
const S32 ALPHAMODE_NONE = 0; // No alpha mask applied
|
|
const S32 ALPHAMODE_BLEND = 1; // Alpha blending mode
|
|
const S32 ALPHAMODE_MASK = 2; // Alpha masking mode
|
|
const S32 BUMPY_TEXTURE = 18; // use supplied normal map
|
|
const S32 SHINY_TEXTURE = 4; // use supplied specular map
|
|
|
|
//
|
|
// "Use texture" label for normal/specular type comboboxes
|
|
// Filled in at initialization from translated strings
|
|
//
|
|
std::string USE_TEXTURE;
|
|
|
|
LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
|
|
{
|
|
// <alchemy>
|
|
LLRender::eTexIndex channel_to_edit = (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
|
|
(mComboMatType ? (LLRender::eTexIndex)mComboMatType->getCurrentIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
|
|
|
|
channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
|
|
channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
|
|
return channel_to_edit;
|
|
// </alchemy>
|
|
}
|
|
|
|
// Things the UI provides...
|
|
//
|
|
// <alchemy>
|
|
LLUUID LLPanelFace::getCurrentNormalMap() { return mBumpyTextureCtrl->getImageAssetID(); }
|
|
LLUUID LLPanelFace::getCurrentSpecularMap() { return mShinyTextureCtrl->getImageAssetID(); }
|
|
U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)mComboAlpha->getCurrentIndex(); }
|
|
// </alchemy>
|
|
|
|
//
|
|
// Methods
|
|
//
|
|
|
|
BOOL LLPanelFace::postBuild()
|
|
{
|
|
// Media button caching
|
|
mMediaInfo = getChildView("media_info");
|
|
mMediaAdd = getChildView("add_media");
|
|
mMediaDelete = getChildView("delete_media");
|
|
|
|
// Label caching
|
|
mLabelGlossy = getChildView("label glossy");
|
|
mLabelEnvironment = getChildView("label environment");
|
|
mLabelShinyColor = getChildView("label shinycolor");
|
|
mLabelAlphaMode = getChildView("label alphamode");
|
|
mLabelMaskCutoff = getChildView("label maskcutoff");
|
|
mLabelBumpy = getChildView("label bumpiness");
|
|
mLabelShiny = getChildView("label shininess");
|
|
mLabelColor = getChildView("color label");
|
|
mLabelGlow = getChildView("glow label");
|
|
mLabelTexGen = getChildView("tex gen");
|
|
|
|
// UICtrl Caching
|
|
mComboShiny = getChild<LLComboBox>("combobox shininess");
|
|
mComboBumpy = getChild<LLComboBox>("combobox bumpiness");
|
|
mComboAlpha = getChild<LLComboBox>("combobox alphamode");
|
|
mCtrlTexScaleU = getChild<LLSpinCtrl>("TexScaleU");
|
|
mCtrlFlipTexScaleU = getChild<LLUICtrl>("flipTextureScaleU");
|
|
mCtrlTexScaleV = getChild<LLSpinCtrl>("TexScaleV");
|
|
mCtrlFlipTexScaleV = getChild<LLUICtrl>("flipTextureScaleV");
|
|
mCtrlTexRot = getChild<LLSpinCtrl>("TexRot");
|
|
mCtrlRpt = getChild<LLUICtrl>("rptctrl");
|
|
mCtrlPlanar = getChild<LLUICtrl>("checkbox planar align");
|
|
mCtrlTexOffsetU = getChild<LLSpinCtrl>("TexOffsetU");
|
|
mCtrlTexOffsetV = getChild<LLSpinCtrl>("TexOffsetV");
|
|
mBumpyScaleU = getChild<LLUICtrl>("bumpyScaleU");
|
|
mBumpyScaleV = getChild<LLUICtrl>("bumpyScaleV");
|
|
mBumpyRot = getChild<LLUICtrl>("bumpyRot");
|
|
mBumpyOffsetU = getChild<LLUICtrl>("bumpyOffsetU");
|
|
mBumpyOffsetV = getChild<LLUICtrl>("bumpyOffsetV");
|
|
mShinyScaleU = getChild<LLUICtrl>("shinyScaleU");
|
|
mShinyScaleV = getChild<LLUICtrl>("shinyScaleV");
|
|
mShinyRot = getChild<LLUICtrl>("shinyRot");
|
|
mShinyOffsetU = getChild<LLUICtrl>("shinyOffsetU");
|
|
mShinyOffsetV = getChild<LLUICtrl>("shinyOffsetV");
|
|
mGlossyCtrl = getChild<LLUICtrl>("glossiness");
|
|
mEnvironmentCtrl = getChild<LLUICtrl>("environment");
|
|
mCtrlMaskCutoff = getChild<LLUICtrl>("maskcutoff");
|
|
mCtrlAlign = getChild<LLUICtrl>("button align");
|
|
mCtrlMapsSync = getChild<LLUICtrl>("checkbox maps sync");
|
|
mCtrlCopy = getChild<LLUICtrl>("copytextures");
|
|
mCtrlPaste = getChild<LLUICtrl>("pastetextures");
|
|
|
|
mComboShiny->setCommitCallback(boost::bind(&LLPanelFace::sendShiny, this, boost::bind(&LLSD::asInteger, _2)));
|
|
mComboBumpy->setCommitCallback(boost::bind(&LLPanelFace::sendBump, this, boost::bind(&LLSD::asInteger, _2)));
|
|
mComboAlpha->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlphaMode, this));
|
|
mCtrlTexScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this));
|
|
mCtrlFlipTexScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitFlip, this, true));
|
|
mCtrlTexScaleV->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this));
|
|
mCtrlFlipTexScaleV->setCommitCallback(boost::bind(&LLPanelFace::onCommitFlip, this, false));
|
|
mCtrlTexRot->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this));
|
|
mCtrlRpt->setCommitCallback(boost::bind(&LLPanelFace::onCommitRepeatsPerMeter, this, _1));
|
|
mCtrlPlanar->setCommitCallback(boost::bind(&LLPanelFace::onCommitPlanarAlign, this));
|
|
mCtrlTexOffsetU->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this));
|
|
mCtrlTexOffsetV->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this));
|
|
|
|
mBumpyScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialBumpyScaleX, this, _2));
|
|
mBumpyScaleV->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialBumpyScaleY, this, _2));
|
|
mBumpyRot->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialBumpyRot, this, _2));
|
|
mBumpyOffsetU->setCommitCallback(boost::bind(LLSelectedTEMaterial::setNormalOffsetX, this, _2));
|
|
mBumpyOffsetV->setCommitCallback(boost::bind(LLSelectedTEMaterial::setNormalOffsetY, this, _2));
|
|
mShinyScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialShinyScaleX, this, _2));
|
|
mShinyScaleV->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialShinyScaleY, this, _2));
|
|
mShinyRot->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialShinyRot, this, _2));
|
|
mShinyOffsetU->setCommitCallback(boost::bind(LLSelectedTEMaterial::setSpecularOffsetX, this, _2));
|
|
mShinyOffsetV->setCommitCallback(boost::bind(LLSelectedTEMaterial::setSpecularOffsetY, this, _2));
|
|
mGlossyCtrl->setCommitCallback(boost::bind(LLSelectedTEMaterial::setSpecularLightExponent, this, boost::bind(&LLSD::asInteger, _2)));
|
|
mEnvironmentCtrl->setCommitCallback(boost::bind(LLSelectedTEMaterial::setEnvironmentIntensity, this, boost::bind(&LLSD::asInteger, _2)));
|
|
mCtrlMaskCutoff->setCommitCallback(boost::bind(LLSelectedTEMaterial::setAlphaMaskCutoff, this, boost::bind(&LLSD::asInteger, _2)));
|
|
|
|
mCtrlAlign->setCommitCallback(boost::bind(&LLPanelFace::onClickAutoFix,this));
|
|
|
|
mCtrlMapsSync->setCommitCallback(boost::bind(&LLPanelFace::onClickMapsSync, this));
|
|
mCtrlCopy->setCommitCallback(boost::bind(&LLPanelFace::onClickCopy,this));
|
|
mCtrlPaste->setCommitCallback(boost::bind(&LLPanelFace::onClickPaste,this));
|
|
|
|
setMouseOpaque(FALSE);
|
|
|
|
mTextureCtrl = getChild<LLTextureCtrl>("texture control");
|
|
if(mTextureCtrl)
|
|
{
|
|
mTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectTexture" )));
|
|
mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );
|
|
mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
|
|
mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
|
|
mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
|
|
mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
|
|
mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
|
|
|
|
mTextureCtrl->setFollowsTop();
|
|
mTextureCtrl->setFollowsLeft();
|
|
mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
|
|
mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
|
|
}
|
|
|
|
mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control");
|
|
if(mShinyTextureCtrl)
|
|
{
|
|
mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectSpecularTexture" )));
|
|
mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) );
|
|
mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) );
|
|
mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) );
|
|
mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
|
|
|
|
mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
|
|
mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
|
|
mShinyTextureCtrl->setFollowsTop();
|
|
mShinyTextureCtrl->setFollowsLeft();
|
|
mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
|
|
mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
|
|
}
|
|
|
|
mBumpyTextureCtrl = getChild<LLTextureCtrl>("bumpytexture control");
|
|
if(mBumpyTextureCtrl)
|
|
{
|
|
mBumpyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectNormalTexture" )));
|
|
mBumpyTextureCtrl->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" )));
|
|
mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) );
|
|
mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) );
|
|
mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) );
|
|
mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
|
|
|
|
mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
|
|
mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
|
|
mBumpyTextureCtrl->setFollowsTop();
|
|
mBumpyTextureCtrl->setFollowsLeft();
|
|
mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
|
|
mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
|
|
}
|
|
|
|
mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
|
|
if(mColorSwatch)
|
|
{
|
|
mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::sendColor, this));
|
|
mColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelColor, this, _2));
|
|
mColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectColor, this, _2));
|
|
mColorSwatch->setFollowsTop();
|
|
mColorSwatch->setFollowsLeft();
|
|
mColorSwatch->setCanApplyImmediately(TRUE);
|
|
}
|
|
|
|
mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
|
|
if(mShinyColorSwatch)
|
|
{
|
|
mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2));
|
|
mShinyColorSwatch->setFollowsTop();
|
|
mShinyColorSwatch->setFollowsLeft();
|
|
mShinyColorSwatch->setCanApplyImmediately(TRUE);
|
|
}
|
|
|
|
mLabelColorTransp = getChild<LLTextBox>("color trans");
|
|
if(mLabelColorTransp)
|
|
{
|
|
mLabelColorTransp->setFollowsTop();
|
|
mLabelColorTransp->setFollowsLeft();
|
|
}
|
|
|
|
mCtrlColorTransp = getChild<LLSpinCtrl>("ColorTrans");
|
|
if(mCtrlColorTransp)
|
|
{
|
|
mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::sendAlpha, this));
|
|
mCtrlColorTransp->setPrecision(0);
|
|
mCtrlColorTransp->setFollowsTop();
|
|
mCtrlColorTransp->setFollowsLeft();
|
|
}
|
|
|
|
mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
|
|
if (mCheckFullbright)
|
|
{
|
|
mCheckFullbright->setCommitCallback(boost::bind(&LLPanelFace::sendFullbright, this));
|
|
}
|
|
|
|
mComboTexGen = getChild<LLComboBox>("combobox texgen");
|
|
if(mComboTexGen)
|
|
{
|
|
mComboTexGen->setCommitCallback(boost::bind(&LLPanelFace::sendTexGen, this));
|
|
mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
|
|
}
|
|
|
|
mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
|
|
if(mComboMatMedia)
|
|
{
|
|
mComboMatMedia->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialsMedia,this));
|
|
mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
|
|
}
|
|
|
|
mComboMatType = getChild<LLComboBox>("combobox mattype");
|
|
if(mComboMatType)
|
|
{
|
|
mComboMatType->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialType, this));
|
|
mComboMatType->selectNthItem(MATTYPE_DIFFUSE);
|
|
}
|
|
|
|
mCtrlGlow = getChild<LLSpinCtrl>("glow");
|
|
if(mCtrlGlow)
|
|
{
|
|
mCtrlGlow->setCommitCallback(boost::bind(&LLPanelFace::sendGlow, this));
|
|
}
|
|
|
|
|
|
clearCtrls();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LLPanelFace::LLPanelFace(const std::string& name)
|
|
: LLPanel(name),
|
|
// <alchemy>
|
|
mMediaInfo(NULL),
|
|
mMediaAdd(NULL),
|
|
mMediaDelete(NULL),
|
|
mLabelGlossy(NULL),
|
|
mLabelEnvironment(NULL),
|
|
mLabelShinyColor(NULL),
|
|
mLabelAlphaMode(NULL),
|
|
mLabelMaskCutoff(NULL),
|
|
mLabelBumpy(NULL),
|
|
mLabelShiny(NULL),
|
|
mLabelColor(NULL),
|
|
mLabelGlow(NULL),
|
|
mLabelTexGen(NULL),
|
|
mComboShiny(NULL),
|
|
mComboBumpy(NULL),
|
|
mComboAlpha(NULL),
|
|
mCtrlTexScaleU(NULL),
|
|
mCtrlFlipTexScaleU(NULL),
|
|
mCtrlTexScaleV(NULL),
|
|
mCtrlFlipTexScaleV(NULL),
|
|
mCtrlTexRot(NULL),
|
|
mCtrlRpt(NULL),
|
|
mCtrlPlanar(NULL),
|
|
mCtrlTexOffsetU(NULL),
|
|
mCtrlTexOffsetV(NULL),
|
|
mBumpyScaleU(NULL),
|
|
mBumpyScaleV(NULL),
|
|
mBumpyRot(NULL),
|
|
mBumpyOffsetU(NULL),
|
|
mBumpyOffsetV(NULL),
|
|
mShinyScaleU(NULL),
|
|
mShinyScaleV(NULL),
|
|
mShinyRot(NULL),
|
|
mShinyOffsetU(NULL),
|
|
mShinyOffsetV(NULL),
|
|
mGlossyCtrl(NULL),
|
|
mEnvironmentCtrl(NULL),
|
|
mCtrlMaskCutoff(NULL),
|
|
mCtrlAlign(NULL),
|
|
mCtrlMapsSync(NULL),
|
|
mCtrlCopy(NULL),
|
|
mCtrlPaste(NULL),
|
|
mTextureCtrl(NULL),
|
|
mShinyTextureCtrl(NULL),
|
|
mBumpyTextureCtrl(NULL),
|
|
mColorSwatch(NULL),
|
|
mShinyColorSwatch(NULL),
|
|
mComboTexGen(NULL),
|
|
mComboMatMedia(NULL),
|
|
mComboMatType(NULL),
|
|
mCheckFullbright(NULL),
|
|
mLabelColorTransp(NULL),
|
|
mCtrlColorTransp(NULL), // transparency = 1 - alpha
|
|
mCtrlGlow(NULL),
|
|
// </alchemy>
|
|
mIsAlpha(false)
|
|
{
|
|
USE_TEXTURE = LLTrans::getString("use_texture");
|
|
}
|
|
|
|
|
|
LLPanelFace::~LLPanelFace()
|
|
{
|
|
// Children all cleaned up by default view destructor.
|
|
}
|
|
|
|
|
|
void LLPanelFace::sendTexture()
|
|
{
|
|
if(!mTextureCtrl) return;
|
|
if( !mTextureCtrl->getTentative() )
|
|
{
|
|
// we grab the item id first, because we want to do a
|
|
// permissions check in the selection manager. ARGH!
|
|
LLUUID id = mTextureCtrl->getImageItemID();
|
|
if(id.isNull())
|
|
{
|
|
id = mTextureCtrl->getImageAssetID();
|
|
}
|
|
LLSelectMgr::getInstance()->selectionSetImage(id);
|
|
}
|
|
}
|
|
|
|
void LLPanelFace::sendBump(U32 bumpiness)
|
|
{
|
|
LLTextureCtrl* bumpytexture_ctrl = mBumpyTextureCtrl;
|
|
if (bumpiness < BUMPY_TEXTURE)
|
|
{
|
|
LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL;
|
|
bumpytexture_ctrl->clear();
|
|
bumpytexture_ctrl->setImageAssetID(LLUUID());
|
|
}
|
|
|
|
updateBumpyControls(bumpiness == BUMPY_TEXTURE, true);
|
|
|
|
LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID();
|
|
|
|
U8 bump = (U8) bumpiness & TEM_BUMP_MASK;
|
|
|
|
// Clear legacy bump to None when using an actual normal map
|
|
//
|
|
if (!current_normal_map.isNull())
|
|
bump = 0;
|
|
|
|
// Set the normal map or reset it to null as appropriate
|
|
//
|
|
LLSelectedTEMaterial::setNormalID(this, current_normal_map);
|
|
|
|
LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
|
|
}
|
|
|
|
void LLPanelFace::sendTexGen()
|
|
{
|
|
if(!mComboTexGen)return;
|
|
U8 tex_gen = (U8) mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT;
|
|
LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen );
|
|
}
|
|
|
|
void LLPanelFace::sendShiny(U32 shininess)
|
|
{
|
|
LLTextureCtrl* texture_ctrl = mShinyTextureCtrl;
|
|
|
|
if (shininess < SHINY_TEXTURE)
|
|
{
|
|
texture_ctrl->clear();
|
|
texture_ctrl->setImageAssetID(LLUUID());
|
|
}
|
|
|
|
LLUUID specmap = getCurrentSpecularMap();
|
|
|
|
U8 shiny = (U8) shininess & TEM_SHINY_MASK;
|
|
if (!specmap.isNull())
|
|
shiny = 0;
|
|
|
|
LLSelectedTEMaterial::setSpecularID(this, specmap);
|
|
|
|
LLSelectMgr::getInstance()->selectionSetShiny( shiny );
|
|
|
|
updateShinyControls(!specmap.isNull(), true);
|
|
|
|
}
|
|
|
|
void LLPanelFace::sendFullbright()
|
|
{
|
|
if(!mCheckFullbright)return;
|
|
U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0;
|
|
LLSelectMgr::getInstance()->selectionSetFullbright( fullbright );
|
|
}
|
|
|
|
void LLPanelFace::sendColor()
|
|
{
|
|
if(!mColorSwatch)return;
|
|
LLColor4 color = mColorSwatch->get();
|
|
|
|
LLSelectMgr::getInstance()->selectionSetColorOnly( color );
|
|
}
|
|
|
|
void LLPanelFace::sendAlpha()
|
|
{
|
|
if(!mCtrlColorTransp)return;
|
|
F32 alpha = (100.f - mCtrlColorTransp->get()) / 100.f;
|
|
|
|
LLSelectMgr::getInstance()->selectionSetAlphaOnly( alpha );
|
|
}
|
|
|
|
|
|
void LLPanelFace::sendGlow()
|
|
{
|
|
llassert(mCtrlGlow);
|
|
if (mCtrlGlow)
|
|
{
|
|
F32 glow = mCtrlGlow->get();
|
|
LLSelectMgr::getInstance()->selectionSetGlow( glow );
|
|
}
|
|
}
|
|
|
|
struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
|
|
{
|
|
LLPanelFaceSetTEFunctor(LLPanelFace* panel) : mPanel(panel) {}
|
|
virtual bool apply(LLViewerObject* object, S32 te)
|
|
{
|
|
BOOL valid;
|
|
F32 value;
|
|
LLSpinCtrl* ctrlTexScaleS = mPanel->mCtrlTexScaleU;
|
|
LLSpinCtrl* ctrlTexScaleT = mPanel->mCtrlTexScaleV;
|
|
LLSpinCtrl* ctrlTexOffsetS = mPanel->mCtrlTexOffsetU;
|
|
LLSpinCtrl* ctrlTexOffsetT = mPanel->mCtrlTexOffsetV;
|
|
LLSpinCtrl* ctrlTexRotation = mPanel->mCtrlTexRot;
|
|
LLComboBox* comboTexGen = mPanel->mComboTexGen;
|
|
llassert(comboTexGen);
|
|
llassert(object);
|
|
|
|
if (ctrlTexScaleS)
|
|
{
|
|
valid = !ctrlTexScaleS->getTentative();
|
|
if (valid)
|
|
{
|
|
value = ctrlTexScaleS->get();
|
|
if (comboTexGen &&
|
|
comboTexGen->getCurrentIndex() == 1)
|
|
{
|
|
value *= 0.5f;
|
|
}
|
|
object->setTEScaleS( te, value );
|
|
}
|
|
}
|
|
|
|
if (ctrlTexScaleT)
|
|
{
|
|
valid = !ctrlTexScaleT->getTentative();
|
|
if (valid)
|
|
{
|
|
value = ctrlTexScaleT->get();
|
|
if (comboTexGen &&
|
|
comboTexGen->getCurrentIndex() == 1)
|
|
{
|
|
value *= 0.5f;
|
|
}
|
|
object->setTEScaleT( te, value );
|
|
}
|
|
}
|
|
|
|
if (ctrlTexOffsetS)
|
|
{
|
|
valid = !ctrlTexOffsetS->getTentative();
|
|
if (valid)
|
|
{
|
|
value = ctrlTexOffsetS->get();
|
|
object->setTEOffsetS( te, value );
|
|
}
|
|
}
|
|
|
|
if (ctrlTexOffsetT)
|
|
{
|
|
valid = !ctrlTexOffsetT->getTentative();
|
|
if (valid)
|
|
{
|
|
value = ctrlTexOffsetT->get();
|
|
object->setTEOffsetT( te, value );
|
|
}
|
|
}
|
|
|
|
if (ctrlTexRotation)
|
|
{
|
|
valid = !ctrlTexRotation->getTentative();
|
|
if (valid)
|
|
{
|
|
value = ctrlTexRotation->get() * DEG_TO_RAD;
|
|
object->setTERotation( te, value );
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
private:
|
|
LLPanelFace* mPanel;
|
|
};
|
|
|
|
// Functor that aligns a face to mCenterFace
|
|
struct LLPanelFaceSetAlignedTEFunctor : public LLSelectedTEFunctor
|
|
{
|
|
LLPanelFaceSetAlignedTEFunctor(LLPanelFace* panel, LLFace* center_face) :
|
|
mPanel(panel),
|
|
mCenterFace(center_face) {}
|
|
|
|
virtual bool apply(LLViewerObject* object, S32 te)
|
|
{
|
|
LLFace* facep = object->mDrawable->getFace(te);
|
|
if (!facep)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool set_aligned = true;
|
|
if (facep == mCenterFace)
|
|
{
|
|
set_aligned = false;
|
|
}
|
|
if (set_aligned)
|
|
{
|
|
LLVector2 uv_offset, uv_scale;
|
|
F32 uv_rot;
|
|
set_aligned = facep->calcAlignedPlanarTE(mCenterFace, &uv_offset, &uv_scale, &uv_rot);
|
|
if (set_aligned)
|
|
{
|
|
object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]);
|
|
object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]);
|
|
object->setTERotation(te, uv_rot);
|
|
}
|
|
}
|
|
if (!set_aligned)
|
|
{
|
|
LLPanelFaceSetTEFunctor setfunc(mPanel);
|
|
setfunc.apply(object, te);
|
|
}
|
|
return true;
|
|
}
|
|
private:
|
|
LLPanelFace* mPanel;
|
|
LLFace* mCenterFace;
|
|
};
|
|
|
|
// Functor that tests if a face is aligned to mCenterFace
|
|
struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor
|
|
{
|
|
LLPanelFaceGetIsAlignedTEFunctor(LLFace* center_face) :
|
|
mCenterFace(center_face) {}
|
|
|
|
virtual bool apply(LLViewerObject* object, S32 te)
|
|
{
|
|
LLFace* facep = object->mDrawable->getFace(te);
|
|
if (!facep)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
|
|
{ //volume face does not exist, can't be aligned
|
|
return false;
|
|
}
|
|
|
|
if (facep == mCenterFace)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
LLVector2 aligned_st_offset, aligned_st_scale;
|
|
F32 aligned_st_rot;
|
|
if ( facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot) )
|
|
{
|
|
const LLTextureEntry* tep = facep->getTextureEntry();
|
|
LLVector2 st_offset, st_scale;
|
|
tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);
|
|
tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);
|
|
F32 st_rot = tep->getRotation();
|
|
// needs a fuzzy comparison, because of fp errors
|
|
if (is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 12) &&
|
|
is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 12) &&
|
|
is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 12) &&
|
|
is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 12) &&
|
|
is_approx_equal_fraction(st_rot, aligned_st_rot, 14))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
private:
|
|
LLFace* mCenterFace;
|
|
};
|
|
|
|
struct LLPanelFaceSendFunctor : public LLSelectedObjectFunctor
|
|
{
|
|
virtual bool apply(LLViewerObject* object)
|
|
{
|
|
object->sendTEUpdate();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void LLPanelFace::sendTextureInfo()
|
|
{
|
|
if ((bool)mCtrlPlanar->getValue().asBoolean())
|
|
{
|
|
LLFace* last_face = NULL;
|
|
bool identical_face = false;
|
|
LLSelectedTE::getFace(last_face, identical_face);
|
|
LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face);
|
|
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
|
|
}
|
|
else
|
|
{
|
|
LLPanelFaceSetTEFunctor setfunc(this);
|
|
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
|
|
}
|
|
|
|
LLPanelFaceSendFunctor sendfunc;
|
|
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
|
|
}
|
|
|
|
void LLPanelFace::getState()
|
|
{
|
|
updateUI();
|
|
}
|
|
|
|
void LLPanelFace::updateUI()
|
|
{ //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible)
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
|
|
|
|
if( objectp
|
|
&& objectp->getPCode() == LL_PCODE_VOLUME
|
|
&& objectp->permModify())
|
|
{
|
|
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
|
|
|
|
// only turn on auto-adjust button if there is a media renderer and the media is loaded
|
|
mCtrlAlign->setEnabled(editable);
|
|
|
|
bool enable_material_controls = (!gSavedSettings.getBOOL("FSSynchronizeTextureMaps"));
|
|
S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
|
|
BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
|
|
&& (selected_count == 1);
|
|
|
|
mCtrlCopy->setEnabled(single_volume && editable);
|
|
mCtrlPaste->setEnabled(editable);
|
|
|
|
LLComboBox* combobox_matmedia = mComboMatMedia;
|
|
if (combobox_matmedia)
|
|
{
|
|
if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL)
|
|
{
|
|
combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL);
|
|
}
|
|
}
|
|
mComboMatMedia->setEnabled(editable);
|
|
|
|
LLComboBox* combobox_mattype = mComboMatType;
|
|
if (combobox_mattype)
|
|
{
|
|
if (combobox_mattype->getCurrentIndex() < MATTYPE_DIFFUSE)
|
|
{
|
|
combobox_mattype->selectNthItem(MATTYPE_DIFFUSE);
|
|
}
|
|
}
|
|
mComboMatType->setEnabled(editable);
|
|
|
|
updateVisibility();
|
|
|
|
bool identical = true; // true because it is anded below
|
|
bool identical_diffuse = false;
|
|
bool identical_norm = false;
|
|
bool identical_spec = false;
|
|
|
|
LLTextureCtrl* texture_ctrl = mTextureCtrl;
|
|
texture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null.
|
|
LLTextureCtrl* shinytexture_ctrl = mShinyTextureCtrl;
|
|
shinytexture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null.
|
|
LLTextureCtrl* bumpytexture_ctrl = mBumpyTextureCtrl;
|
|
bumpytexture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null.
|
|
|
|
LLUUID id;
|
|
LLUUID normmap_id;
|
|
LLUUID specmap_id;
|
|
|
|
// Color swatch
|
|
{
|
|
mLabelColor->setEnabled(editable);
|
|
}
|
|
|
|
LLColor4 color = LLColor4::white;
|
|
bool identical_color =false;
|
|
|
|
if(mColorSwatch)
|
|
{
|
|
LLSelectedTE::getColor(color, identical_color);
|
|
|
|
mColorSwatch->setOriginal(color);
|
|
mColorSwatch->set(color, TRUE);
|
|
|
|
mColorSwatch->setValid(editable);
|
|
mColorSwatch->setEnabled( editable );
|
|
mColorSwatch->setCanApplyImmediately( editable );
|
|
}
|
|
|
|
// Color transparency
|
|
mLabelColorTransp->setEnabled(editable);
|
|
|
|
F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
|
|
mCtrlColorTransp->setValue(editable ? transparency : 0);
|
|
mCtrlColorTransp->setEnabled(editable);
|
|
|
|
// Specular map
|
|
LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec);
|
|
|
|
U8 shiny = 0;
|
|
bool identical_shiny = false;
|
|
|
|
// Shiny
|
|
LLSelectedTE::getShiny(shiny, identical_shiny);
|
|
identical = identical && identical_shiny;
|
|
|
|
shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE;
|
|
|
|
if (mComboShiny)
|
|
{
|
|
mComboShiny->selectNthItem((S32)shiny);
|
|
}
|
|
|
|
mLabelShiny->setEnabled(editable);
|
|
mComboShiny->setEnabled(editable);
|
|
|
|
mLabelGlossy->setEnabled(editable);
|
|
mGlossyCtrl->setEnabled(editable);
|
|
|
|
mLabelEnvironment->setEnabled(editable);
|
|
mEnvironmentCtrl->setEnabled(editable);
|
|
mLabelShinyColor->setEnabled(editable);
|
|
|
|
mComboShiny->setTentative(!identical_spec);
|
|
mGlossyCtrl->setTentative(!identical_spec);
|
|
mEnvironmentCtrl->setTentative(!identical_spec);
|
|
mShinyColorSwatch->setTentative(!identical_spec);
|
|
|
|
if(mShinyColorSwatch)
|
|
{
|
|
mShinyColorSwatch->setValid(editable);
|
|
mShinyColorSwatch->setEnabled( editable );
|
|
mShinyColorSwatch->setCanApplyImmediately( editable );
|
|
}
|
|
|
|
U8 bumpy = 0;
|
|
// Bumpy
|
|
{
|
|
bool identical_bumpy = false;
|
|
LLSelectedTE::getBumpmap(bumpy,identical_bumpy);
|
|
|
|
LLUUID norm_map_id = getCurrentNormalMap();
|
|
LLCtrlSelectionInterface* combobox_bumpiness = mComboBumpy;
|
|
|
|
bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
|
|
|
|
if (combobox_bumpiness)
|
|
{
|
|
combobox_bumpiness->selectNthItem((S32)bumpy);
|
|
}
|
|
|
|
mComboBumpy->setEnabled(editable);
|
|
mComboBumpy->setTentative(!identical_bumpy);
|
|
mLabelBumpy->setEnabled(editable);
|
|
}
|
|
|
|
// Texture
|
|
{
|
|
LLSelectedTE::getTexId(id,identical_diffuse);
|
|
|
|
// Normal map
|
|
LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm);
|
|
|
|
mIsAlpha = FALSE;
|
|
LLGLenum image_format = GL_RGB;
|
|
bool identical_image_format = false;
|
|
LLSelectedTE::getImageFormat(image_format, identical_image_format);
|
|
|
|
mIsAlpha = FALSE;
|
|
switch (image_format)
|
|
{
|
|
case GL_RGBA:
|
|
case GL_ALPHA:
|
|
{
|
|
mIsAlpha = TRUE;
|
|
}
|
|
break;
|
|
|
|
case GL_RGB: break;
|
|
default:
|
|
{
|
|
LL_WARNS("Materials") << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(LLViewerMedia::textureHasMedia(id))
|
|
{
|
|
mCtrlAlign->setEnabled(editable);
|
|
}
|
|
|
|
// Diffuse Alpha Mode
|
|
|
|
// Init to the default that is appropriate for the alpha content of the asset
|
|
//
|
|
U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
|
|
|
|
bool identical_alpha_mode = false;
|
|
|
|
// See if that's been overridden by a material setting for same...
|
|
//
|
|
LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha);
|
|
|
|
LLCtrlSelectionInterface* combobox_alphamode = mComboAlpha;
|
|
if (combobox_alphamode)
|
|
{
|
|
//it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
|
|
// Want masking? Want emissive? Tough! You get BLEND!
|
|
alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode;
|
|
|
|
// ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none
|
|
alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
|
|
|
|
combobox_alphamode->selectNthItem(alpha_mode);
|
|
}
|
|
|
|
updateAlphaControls();
|
|
|
|
if (texture_ctrl)
|
|
{
|
|
if (identical_diffuse)
|
|
{
|
|
texture_ctrl->setTentative( FALSE );
|
|
texture_ctrl->setEnabled( editable );
|
|
texture_ctrl->setImageAssetID( id );
|
|
mComboAlpha->setEnabled(editable && mIsAlpha && transparency <= 0.f);
|
|
mLabelAlphaMode->setEnabled(editable && mIsAlpha);
|
|
mCtrlMaskCutoff->setEnabled(editable && mIsAlpha);
|
|
mLabelMaskCutoff->setEnabled(editable && mIsAlpha);
|
|
}
|
|
else if (id.isNull())
|
|
{
|
|
// None selected
|
|
texture_ctrl->setTentative( FALSE );
|
|
texture_ctrl->setEnabled( FALSE );
|
|
texture_ctrl->setImageAssetID( LLUUID::null );
|
|
mComboAlpha->setEnabled( FALSE );
|
|
mLabelAlphaMode->setEnabled( FALSE );
|
|
mCtrlMaskCutoff->setEnabled( FALSE);
|
|
mLabelMaskCutoff->setEnabled( FALSE );
|
|
}
|
|
else
|
|
{
|
|
// Tentative: multiple selected with different textures
|
|
texture_ctrl->setTentative( TRUE );
|
|
texture_ctrl->setEnabled( editable );
|
|
texture_ctrl->setImageAssetID( id );
|
|
mComboAlpha->setEnabled(editable && mIsAlpha && transparency <= 0.f);
|
|
mLabelAlphaMode->setEnabled(editable && mIsAlpha);
|
|
mCtrlMaskCutoff->setEnabled(editable && mIsAlpha);
|
|
mLabelMaskCutoff->setEnabled(editable && mIsAlpha);
|
|
}
|
|
}
|
|
|
|
if (shinytexture_ctrl)
|
|
{
|
|
if (identical_spec && (shiny == SHINY_TEXTURE))
|
|
{
|
|
shinytexture_ctrl->setTentative( FALSE );
|
|
shinytexture_ctrl->setEnabled( editable );
|
|
shinytexture_ctrl->setImageAssetID( specmap_id );
|
|
}
|
|
else if (specmap_id.isNull())
|
|
{
|
|
shinytexture_ctrl->setTentative( FALSE );
|
|
shinytexture_ctrl->setEnabled( editable );
|
|
shinytexture_ctrl->setImageAssetID( LLUUID::null );
|
|
}
|
|
else
|
|
{
|
|
shinytexture_ctrl->setTentative( TRUE );
|
|
shinytexture_ctrl->setEnabled( editable );
|
|
shinytexture_ctrl->setImageAssetID( specmap_id );
|
|
}
|
|
}
|
|
|
|
if (bumpytexture_ctrl)
|
|
{
|
|
if (identical_norm && (bumpy == BUMPY_TEXTURE))
|
|
{
|
|
bumpytexture_ctrl->setTentative( FALSE );
|
|
bumpytexture_ctrl->setEnabled( editable );
|
|
bumpytexture_ctrl->setImageAssetID( normmap_id );
|
|
}
|
|
else if (normmap_id.isNull())
|
|
{
|
|
bumpytexture_ctrl->setTentative( FALSE );
|
|
bumpytexture_ctrl->setEnabled( editable );
|
|
bumpytexture_ctrl->setImageAssetID( LLUUID::null );
|
|
}
|
|
else
|
|
{
|
|
bumpytexture_ctrl->setTentative( TRUE );
|
|
bumpytexture_ctrl->setEnabled( editable );
|
|
bumpytexture_ctrl->setImageAssetID( normmap_id );
|
|
}
|
|
}
|
|
}
|
|
|
|
// planar align
|
|
bool align_planar = false;
|
|
bool identical_planar_aligned = false;
|
|
{
|
|
LLUICtrl* cb_planar_align = mCtrlPlanar;
|
|
align_planar = (cb_planar_align && cb_planar_align->getValue().asBoolean());
|
|
|
|
bool enabled = (editable && isIdenticalPlanarTexgen());
|
|
mCtrlPlanar->setValue(align_planar && enabled);
|
|
mCtrlPlanar->setEnabled(enabled);
|
|
|
|
if (align_planar && enabled)
|
|
{
|
|
LLFace* last_face = NULL;
|
|
bool identical_face = false;
|
|
LLSelectedTE::getFace(last_face, identical_face);
|
|
|
|
LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face);
|
|
// this will determine if the texture param controls are tentative:
|
|
identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func);
|
|
}
|
|
}
|
|
|
|
// Needs to be public and before tex scale settings below to properly reflect
|
|
// behavior when in planar vs default texgen modes in the
|
|
// NORSPEC-84 et al
|
|
//
|
|
LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
|
|
bool identical_texgen = true;
|
|
bool identical_planar_texgen = false;
|
|
|
|
{
|
|
LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
|
|
identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
|
|
}
|
|
|
|
// Texture scale
|
|
{
|
|
bool identical_diff_scale_s = false;
|
|
bool identical_spec_scale_s = false;
|
|
bool identical_norm_scale_s = false;
|
|
|
|
identical = align_planar ? identical_planar_aligned : identical;
|
|
|
|
F32 diff_scale_s = 1.f;
|
|
F32 spec_scale_s = 1.f;
|
|
F32 norm_scale_s = 1.f;
|
|
|
|
LLSelectedTE::getScaleS(diff_scale_s, identical_diff_scale_s);
|
|
LLSelectedTEMaterial::getSpecularRepeatX(spec_scale_s, identical_spec_scale_s);
|
|
LLSelectedTEMaterial::getNormalRepeatX(norm_scale_s, identical_norm_scale_s);
|
|
|
|
diff_scale_s = editable ? diff_scale_s : 1.0f;
|
|
diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
|
|
|
|
norm_scale_s = editable ? norm_scale_s : 1.0f;
|
|
norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
|
|
|
|
spec_scale_s = editable ? spec_scale_s : 1.0f;
|
|
spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
|
|
|
|
mCtrlTexScaleU->setValue(diff_scale_s);
|
|
mShinyScaleU->setValue(spec_scale_s);
|
|
mBumpyScaleU->setValue(norm_scale_s);
|
|
|
|
mCtrlTexScaleU->setEnabled(editable);
|
|
mShinyScaleU->setEnabled(editable && specmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
mBumpyScaleU->setEnabled(editable && normmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
|
|
BOOL diff_scale_tentative = !(identical && identical_diff_scale_s);
|
|
BOOL norm_scale_tentative = !(identical && identical_norm_scale_s);
|
|
BOOL spec_scale_tentative = !(identical && identical_spec_scale_s);
|
|
|
|
mCtrlTexScaleU->setTentative( LLSD(diff_scale_tentative));
|
|
mShinyScaleU->setTentative(LLSD(spec_scale_tentative));
|
|
mBumpyScaleU->setTentative(LLSD(norm_scale_tentative));
|
|
|
|
// <FS:CR> FIRE-11407 - Materials alignment
|
|
mCtrlMapsSync->setEnabled(editable && (specmap_id.notNull() || normmap_id.notNull()));
|
|
// </FS:CR>
|
|
}
|
|
|
|
{
|
|
bool identical_diff_scale_t = false;
|
|
bool identical_spec_scale_t = false;
|
|
bool identical_norm_scale_t = false;
|
|
|
|
F32 diff_scale_t = 1.f;
|
|
F32 spec_scale_t = 1.f;
|
|
F32 norm_scale_t = 1.f;
|
|
|
|
LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t);
|
|
LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t);
|
|
LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t);
|
|
|
|
diff_scale_t = editable ? diff_scale_t : 1.0f;
|
|
diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
|
|
|
|
norm_scale_t = editable ? norm_scale_t : 1.0f;
|
|
norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
|
|
|
|
spec_scale_t = editable ? spec_scale_t : 1.0f;
|
|
spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
|
|
|
|
BOOL diff_scale_tentative = !identical_diff_scale_t;
|
|
BOOL norm_scale_tentative = !identical_norm_scale_t;
|
|
BOOL spec_scale_tentative = !identical_spec_scale_t;
|
|
|
|
mCtrlTexScaleV->setEnabled(editable);
|
|
mShinyScaleV->setEnabled(editable && specmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
mBumpyScaleV->setEnabled(editable && normmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
|
|
mCtrlTexScaleV->setValue(diff_scale_t);
|
|
mShinyScaleV->setValue(norm_scale_t);
|
|
mBumpyScaleV->setValue(spec_scale_t);
|
|
|
|
mCtrlTexScaleV->setTentative(LLSD(diff_scale_tentative));
|
|
mShinyScaleV->setTentative(LLSD(norm_scale_tentative));
|
|
mBumpyScaleV->setTentative(LLSD(spec_scale_tentative));
|
|
}
|
|
|
|
// Texture offset
|
|
{
|
|
bool identical_diff_offset_s = false;
|
|
bool identical_norm_offset_s = false;
|
|
bool identical_spec_offset_s = false;
|
|
|
|
F32 diff_offset_s = 0.0f;
|
|
F32 norm_offset_s = 0.0f;
|
|
F32 spec_offset_s = 0.0f;
|
|
|
|
LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s);
|
|
LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s);
|
|
LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s);
|
|
|
|
BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s);
|
|
BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s);
|
|
BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s);
|
|
|
|
mCtrlTexOffsetU->setValue( editable ? diff_offset_s : 0.0f);
|
|
mBumpyOffsetU->setValue(editable ? norm_offset_s : 0.0f);
|
|
mShinyOffsetU->setValue(editable ? spec_offset_s : 0.0f);
|
|
|
|
mCtrlTexOffsetU->setTentative(LLSD(diff_offset_u_tentative));
|
|
mShinyOffsetU->setTentative(LLSD(norm_offset_u_tentative));
|
|
mBumpyOffsetU->setTentative(LLSD(spec_offset_u_tentative));
|
|
|
|
mCtrlTexOffsetU->setEnabled(editable);
|
|
mShinyOffsetU->setEnabled(editable && specmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
mBumpyOffsetU->setEnabled(editable && normmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
}
|
|
|
|
{
|
|
bool identical_diff_offset_t = false;
|
|
bool identical_norm_offset_t = false;
|
|
bool identical_spec_offset_t = false;
|
|
|
|
F32 diff_offset_t = 0.0f;
|
|
F32 norm_offset_t = 0.0f;
|
|
F32 spec_offset_t = 0.0f;
|
|
|
|
LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t);
|
|
LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t);
|
|
LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t);
|
|
|
|
BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t);
|
|
BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t);
|
|
BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t);
|
|
|
|
mCtrlTexOffsetV->setValue( editable ? diff_offset_t : 0.0f);
|
|
mBumpyOffsetV->setValue(editable ? norm_offset_t : 0.0f);
|
|
mShinyOffsetV->setValue(editable ? spec_offset_t : 0.0f);
|
|
|
|
mCtrlTexOffsetV->setTentative(LLSD(diff_offset_v_tentative));
|
|
mShinyOffsetV->setTentative(LLSD(norm_offset_v_tentative));
|
|
mBumpyOffsetV->setTentative(LLSD(spec_offset_v_tentative));
|
|
|
|
mCtrlTexOffsetV->setEnabled(editable);
|
|
mShinyOffsetV->setEnabled(editable && specmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
mBumpyOffsetV->setEnabled(editable && normmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
}
|
|
|
|
// Texture rotation
|
|
{
|
|
bool identical_diff_rotation = false;
|
|
bool identical_norm_rotation = false;
|
|
bool identical_spec_rotation = false;
|
|
|
|
F32 diff_rotation = 0.f;
|
|
F32 norm_rotation = 0.f;
|
|
F32 spec_rotation = 0.f;
|
|
|
|
LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation);
|
|
LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation);
|
|
LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation);
|
|
|
|
BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation);
|
|
BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation);
|
|
BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation);
|
|
|
|
F32 diff_rot_deg = diff_rotation * RAD_TO_DEG;
|
|
F32 norm_rot_deg = norm_rotation * RAD_TO_DEG;
|
|
F32 spec_rot_deg = spec_rotation * RAD_TO_DEG;
|
|
|
|
mCtrlTexRot->setEnabled(editable);
|
|
mShinyRot->setEnabled(editable && specmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
mBumpyRot->setEnabled(editable && normmap_id.notNull()
|
|
&& enable_material_controls); // <FS:CR> Materials alignment
|
|
|
|
mCtrlTexRot->setTentative(diff_rot_tentative);
|
|
mShinyRot->setTentative(LLSD(norm_rot_tentative));
|
|
mBumpyRot->setTentative(LLSD(spec_rot_tentative));
|
|
|
|
mCtrlTexRot->setValue( editable ? diff_rot_deg : 0.0f);
|
|
mShinyRot->setValue(editable ? spec_rot_deg : 0.0f);
|
|
mBumpyRot->setValue(editable ? norm_rot_deg : 0.0f);
|
|
}
|
|
|
|
{
|
|
F32 glow = 0.f;
|
|
bool identical_glow = false;
|
|
LLSelectedTE::getGlow(glow,identical_glow);
|
|
mCtrlGlow->setValue(glow);
|
|
mCtrlGlow->setTentative(!identical_glow);
|
|
mCtrlGlow->setEnabled(editable);
|
|
mLabelGlow->setEnabled(editable);
|
|
}
|
|
|
|
{
|
|
LLCtrlSelectionInterface* combobox_texgen = mComboTexGen;
|
|
if (combobox_texgen)
|
|
{
|
|
// Maps from enum to combobox entry index
|
|
combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1);
|
|
}
|
|
|
|
mComboTexGen->setEnabled(editable);
|
|
mComboTexGen->setTentative(!identical);
|
|
mLabelTexGen->setEnabled(editable);
|
|
|
|
/* Singu Note: Dead code
|
|
if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)
|
|
{
|
|
// EXP-1507 (change label based on the mapping mode)
|
|
getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter"));
|
|
}
|
|
else
|
|
if (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT)
|
|
{
|
|
getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face"));
|
|
}
|
|
*/
|
|
}
|
|
|
|
{
|
|
U8 fullbright_flag = 0;
|
|
bool identical_fullbright = false;
|
|
|
|
LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright);
|
|
|
|
mCheckFullbright->setValue((S32)(fullbright_flag != 0));
|
|
mCheckFullbright->setEnabled(editable);
|
|
mCheckFullbright->setTentative(!identical_fullbright);
|
|
}
|
|
|
|
|
|
// Repeats per meter
|
|
{
|
|
F32 repeats_diff = 1.f;
|
|
F32 repeats_norm = 1.f;
|
|
F32 repeats_spec = 1.f;
|
|
|
|
bool identical_diff_repeats = false;
|
|
bool identical_norm_repeats = false;
|
|
bool identical_spec_repeats = false;
|
|
|
|
LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats);
|
|
LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats);
|
|
LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats);
|
|
|
|
if (mComboTexGen)
|
|
{
|
|
S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
|
|
BOOL enabled = editable && (index != 1);
|
|
BOOL identical_repeats = true;
|
|
F32 repeats = 1.0f;
|
|
|
|
U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE;
|
|
|
|
LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
|
|
|
|
switch (material_type)
|
|
{
|
|
default:
|
|
case MATTYPE_DIFFUSE:
|
|
{
|
|
enabled = editable && !id.isNull();
|
|
identical_repeats = identical_diff_repeats;
|
|
repeats = repeats_diff;
|
|
}
|
|
break;
|
|
|
|
case MATTYPE_SPECULAR:
|
|
{
|
|
enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull())
|
|
&& enable_material_controls); // <FS:CR> Materials Alignment
|
|
identical_repeats = identical_spec_repeats;
|
|
repeats = repeats_spec;
|
|
}
|
|
break;
|
|
|
|
case MATTYPE_NORMAL:
|
|
{
|
|
enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull())
|
|
&& enable_material_controls); // <FS:CR> Materials Alignment
|
|
identical_repeats = identical_norm_repeats;
|
|
repeats = repeats_norm;
|
|
}
|
|
break;
|
|
}
|
|
|
|
BOOL repeats_tentative = !identical_repeats;
|
|
|
|
mCtrlRpt->setEnabled(identical_planar_texgen ? FALSE : enabled);
|
|
mCtrlRpt->setValue(editable ? repeats : 1.0f);
|
|
mCtrlRpt->setTentative(LLSD(repeats_tentative));
|
|
|
|
// <FS:CR> FIRE-11407 - Flip buttons
|
|
mCtrlFlipTexScaleU->setEnabled(enabled);
|
|
mCtrlFlipTexScaleV->setEnabled(enabled);
|
|
// </FS:CR>
|
|
}
|
|
}
|
|
|
|
// Materials
|
|
{
|
|
LLMaterialPtr material;
|
|
LLSelectedTEMaterial::getCurrent(material, identical);
|
|
|
|
if (material && editable)
|
|
{
|
|
LL_DEBUGS("Materials: OnMaterialsLoaded:") << material->asLLSD() << LL_ENDL;
|
|
|
|
// Alpha
|
|
LLCtrlSelectionInterface* combobox_alphamode =
|
|
mComboAlpha;
|
|
if (combobox_alphamode)
|
|
{
|
|
U32 alpha_mode = material->getDiffuseAlphaMode();
|
|
|
|
if (transparency > 0.f)
|
|
{ //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
|
|
alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
|
|
}
|
|
|
|
if (!mIsAlpha)
|
|
{ // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none
|
|
alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
|
|
}
|
|
|
|
combobox_alphamode->selectNthItem(alpha_mode);
|
|
}
|
|
mCtrlMaskCutoff->setValue(material->getAlphaMaskCutoff());
|
|
updateAlphaControls();
|
|
|
|
identical_planar_texgen = isIdenticalPlanarTexgen();
|
|
|
|
// Shiny (specular)
|
|
F32 offset_x, offset_y, repeat_x, repeat_y, rot;
|
|
LLTextureCtrl* texture_ctrl = mShinyTextureCtrl;
|
|
texture_ctrl->setImageAssetID(material->getSpecularID());
|
|
|
|
if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE))
|
|
{
|
|
material->getSpecularOffset(offset_x,offset_y);
|
|
material->getSpecularRepeat(repeat_x,repeat_y);
|
|
|
|
if (identical_planar_texgen)
|
|
{
|
|
repeat_x *= 2.0f;
|
|
repeat_y *= 2.0f;
|
|
}
|
|
|
|
rot = material->getSpecularRotation();
|
|
mShinyScaleU->setValue(repeat_x);
|
|
mShinyScaleV->setValue(repeat_y);
|
|
mShinyRot->setValue(rot*RAD_TO_DEG);
|
|
mShinyOffsetU->setValue(offset_x);
|
|
mShinyOffsetV->setValue(offset_y);
|
|
mGlossyCtrl->setValue(material->getSpecularLightExponent());
|
|
mEnvironmentCtrl->setValue(material->getEnvironmentIntensity());
|
|
|
|
updateShinyControls(!material->getSpecularID().isNull(), true);
|
|
}
|
|
|
|
// Assert desired colorswatch color to match material AFTER updateShinyControls
|
|
// to avoid getting overwritten with the default on some UI state changes.
|
|
//
|
|
if (!material->getSpecularID().isNull())
|
|
{
|
|
mShinyColorSwatch->setOriginal(material->getSpecularLightColor());
|
|
mShinyColorSwatch->set(material->getSpecularLightColor(),TRUE);
|
|
}
|
|
|
|
// Bumpy (normal)
|
|
texture_ctrl = mBumpyTextureCtrl;
|
|
texture_ctrl->setImageAssetID(material->getNormalID());
|
|
|
|
if (!material->getNormalID().isNull())
|
|
{
|
|
material->getNormalOffset(offset_x,offset_y);
|
|
material->getNormalRepeat(repeat_x,repeat_y);
|
|
|
|
if (identical_planar_texgen)
|
|
{
|
|
repeat_x *= 2.0f;
|
|
repeat_y *= 2.0f;
|
|
}
|
|
|
|
rot = material->getNormalRotation();
|
|
mBumpyScaleU->setValue(repeat_x);
|
|
mBumpyScaleV->setValue(repeat_y);
|
|
mBumpyRot->setValue(rot*RAD_TO_DEG);
|
|
mBumpyOffsetU->setValue(offset_x);
|
|
mBumpyOffsetV->setValue(offset_y);
|
|
|
|
updateBumpyControls(!material->getNormalID().isNull(), true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set variable values for numeric expressions
|
|
LLCalc* calcp = LLCalc::getInstance();
|
|
calcp->setVar(LLCalc::TEX_U_SCALE, mCtrlTexScaleU->getValue().asReal());
|
|
calcp->setVar(LLCalc::TEX_V_SCALE, mCtrlTexScaleV->getValue().asReal());
|
|
calcp->setVar(LLCalc::TEX_U_OFFSET, mCtrlTexOffsetU->getValue().asReal());
|
|
calcp->setVar(LLCalc::TEX_V_OFFSET, mCtrlTexOffsetV->getValue().asReal());
|
|
calcp->setVar(LLCalc::TEX_ROTATION, mCtrlTexRot->getValue().asReal());
|
|
calcp->setVar(LLCalc::TEX_TRANSPARENCY, mCtrlColorTransp->getValue().asReal());
|
|
calcp->setVar(LLCalc::TEX_GLOW, mCtrlGlow->getValue().asReal());
|
|
}
|
|
else
|
|
{
|
|
// Disable all UICtrls
|
|
clearCtrls();
|
|
|
|
// Disable non-UICtrls
|
|
LLTextureCtrl* texture_ctrl = mTextureCtrl;
|
|
if(texture_ctrl)
|
|
{
|
|
texture_ctrl->setImageAssetID( LLUUID::null );
|
|
texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl.
|
|
// texture_ctrl->setValid(FALSE);
|
|
}
|
|
if(mColorSwatch)
|
|
{
|
|
mColorSwatch->setEnabled( FALSE );
|
|
mColorSwatch->setFallbackImageName("locked_image.j2c" );
|
|
mColorSwatch->setValid(FALSE);
|
|
}
|
|
mLabelColorTransp->setEnabled(FALSE);
|
|
/* Singu Note: This is missing in xml
|
|
getChildView("rpt")->setEnabled(FALSE);
|
|
getChildView("tex offset")->setEnabled(FALSE);
|
|
*/
|
|
mLabelTexGen->setEnabled(FALSE);
|
|
mLabelShiny->setEnabled(FALSE);
|
|
mLabelBumpy->setEnabled(FALSE);
|
|
mCtrlAlign->setEnabled(FALSE);
|
|
//getChildView("has media")->setEnabled(FALSE);
|
|
//getChildView("media info set")->setEnabled(FALSE);
|
|
|
|
updateVisibility();
|
|
|
|
// Set variable values for numeric expressions
|
|
LLCalc* calcp = LLCalc::getInstance();
|
|
calcp->clearVar(LLCalc::TEX_U_SCALE);
|
|
calcp->clearVar(LLCalc::TEX_V_SCALE);
|
|
calcp->clearVar(LLCalc::TEX_U_OFFSET);
|
|
calcp->clearVar(LLCalc::TEX_V_OFFSET);
|
|
calcp->clearVar(LLCalc::TEX_ROTATION);
|
|
calcp->clearVar(LLCalc::TEX_TRANSPARENCY);
|
|
calcp->clearVar(LLCalc::TEX_GLOW);
|
|
}
|
|
}
|
|
|
|
|
|
void LLPanelFace::refresh()
|
|
{
|
|
LL_DEBUGS("Materials") << LL_ENDL;
|
|
getState();
|
|
}
|
|
|
|
//
|
|
// Static functions
|
|
//
|
|
|
|
// static
|
|
F32 LLPanelFace::valueGlow(LLViewerObject* object, S32 face)
|
|
{
|
|
return (F32)(object->getTE(face)->getGlow());
|
|
}
|
|
|
|
|
|
void LLPanelFace::onCommitShinyColor(const LLSD& data)
|
|
{
|
|
LLSelectedTEMaterial::setSpecularLightColor(this, mShinyColorSwatch->get());
|
|
}
|
|
|
|
void LLPanelFace::onCancelColor(const LLSD& data)
|
|
{
|
|
LLSelectMgr::getInstance()->selectionRevertColors();
|
|
}
|
|
|
|
void LLPanelFace::onSelectColor(const LLSD& data)
|
|
{
|
|
LLSelectMgr::getInstance()->saveSelectedObjectColors();
|
|
sendColor();
|
|
}
|
|
|
|
void LLPanelFace::onCommitMaterialsMedia()
|
|
{
|
|
// Force to default states to side-step problems with menu contents
|
|
// and generally reflecting old state when switching tabs or objects
|
|
//
|
|
updateShinyControls(false,true);
|
|
updateBumpyControls(false,true);
|
|
updateUI();
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::updateVisibility()
|
|
{
|
|
LLComboBox* combo_matmedia = mComboMatMedia;
|
|
LLComboBox* combo_mattype = mComboMatType;
|
|
LLComboBox* combo_shininess = mComboShiny;
|
|
LLComboBox* combo_bumpiness = mComboBumpy;
|
|
if (!combo_mattype || !combo_matmedia || !combo_shininess || !combo_bumpiness)
|
|
{
|
|
LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
|
|
return;
|
|
}
|
|
U32 materials_media = combo_matmedia->getCurrentIndex();
|
|
U32 material_type = combo_mattype->getCurrentIndex();
|
|
bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
|
|
bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled()));
|
|
bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled();
|
|
bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
|
|
mComboMatType->setVisible(!show_media);
|
|
// <FS:CR> FIRE-11407 - Be consistant and hide this with the other controls
|
|
//mCtrlRpt->setVisible(true);
|
|
mCtrlRpt->setVisible(combo_matmedia->getEnabled());
|
|
// and other additions...
|
|
mCtrlFlipTexScaleU->setVisible(combo_matmedia->getEnabled());
|
|
mCtrlFlipTexScaleV->setVisible(combo_matmedia->getEnabled());
|
|
// </FS:CR>
|
|
|
|
// Media controls
|
|
mMediaInfo->setVisible(show_media);
|
|
mMediaAdd->setVisible(show_media);
|
|
mMediaDelete->setVisible(show_media);
|
|
mCtrlAlign->setVisible(show_media);
|
|
|
|
// Diffuse texture controls
|
|
mTextureCtrl->setVisible(show_texture && !show_media);
|
|
mLabelAlphaMode->setVisible(show_texture && !show_media);
|
|
mComboAlpha->setVisible(show_texture && !show_media);
|
|
mLabelMaskCutoff->setVisible(false);
|
|
mCtrlMaskCutoff->setVisible(false);
|
|
if (show_texture && !show_media)
|
|
{
|
|
updateAlphaControls();
|
|
}
|
|
mCtrlTexScaleU->setVisible(show_texture);
|
|
mCtrlTexScaleV->setVisible(show_texture);
|
|
mCtrlTexRot->setVisible(show_texture);
|
|
mCtrlTexOffsetU->setVisible(show_texture);
|
|
mCtrlTexOffsetV->setVisible(show_texture);
|
|
|
|
// Specular map controls
|
|
mShinyTextureCtrl->setVisible(show_shininess);
|
|
mComboShiny->setVisible(show_shininess);
|
|
mLabelShiny->setVisible(show_shininess);
|
|
mLabelGlossy->setVisible(false);
|
|
mGlossyCtrl->setVisible(false);
|
|
mLabelEnvironment->setVisible(false);
|
|
mEnvironmentCtrl->setVisible(false);
|
|
mLabelShinyColor->setVisible(false);
|
|
mShinyColorSwatch->setVisible(false);
|
|
if (show_shininess)
|
|
{
|
|
updateShinyControls();
|
|
}
|
|
mShinyScaleU->setVisible(show_shininess);
|
|
mShinyScaleV->setVisible(show_shininess);
|
|
mShinyRot->setVisible(show_shininess);
|
|
mShinyOffsetU->setVisible(show_shininess);
|
|
mShinyOffsetV->setVisible(show_shininess);
|
|
|
|
// Normal map controls
|
|
if (show_bumpiness)
|
|
{
|
|
updateBumpyControls();
|
|
}
|
|
mBumpyTextureCtrl->setVisible(show_bumpiness);
|
|
mComboBumpy->setVisible(show_bumpiness);
|
|
mLabelBumpy->setVisible(show_bumpiness);
|
|
mBumpyScaleU->setVisible(show_bumpiness);
|
|
mBumpyScaleV->setVisible(show_bumpiness);
|
|
mBumpyRot->setVisible(show_bumpiness);
|
|
mBumpyOffsetU->setVisible(show_bumpiness);
|
|
mBumpyOffsetV->setVisible(show_bumpiness);
|
|
}
|
|
|
|
void LLPanelFace::onCommitMaterialType()
|
|
{
|
|
// Force to default states to side-step problems with menu contents
|
|
// and generally reflecting old state when switching tabs or objects
|
|
//
|
|
updateShinyControls(false,true);
|
|
updateBumpyControls(false,true);
|
|
updateUI();
|
|
}
|
|
|
|
void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_shiny_combobox)
|
|
{
|
|
LLTextureCtrl* texture_ctrl = mShinyTextureCtrl;
|
|
LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID();
|
|
LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL;
|
|
LLComboBox* comboShiny = mComboShiny;
|
|
|
|
if(mess_with_shiny_combobox)
|
|
{
|
|
if (!comboShiny)
|
|
{
|
|
return;
|
|
}
|
|
if (!shiny_texture_ID.isNull() && is_setting_texture)
|
|
{
|
|
if (!comboShiny->itemExists(USE_TEXTURE))
|
|
{
|
|
comboShiny->add(USE_TEXTURE);
|
|
}
|
|
comboShiny->setSimple(USE_TEXTURE);
|
|
}
|
|
else
|
|
{
|
|
if (comboShiny->itemExists(USE_TEXTURE))
|
|
{
|
|
comboShiny->remove(SHINY_TEXTURE);
|
|
comboShiny->selectFirstItem();
|
|
}
|
|
}
|
|
}
|
|
|
|
LLComboBox* combo_matmedia = mComboMatMedia;
|
|
LLComboBox* combo_mattype =mComboMatType;
|
|
U32 materials_media = combo_matmedia->getCurrentIndex();
|
|
U32 material_type = combo_mattype->getCurrentIndex();
|
|
bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
|
|
bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
|
|
U32 shiny_value = comboShiny->getCurrentIndex();
|
|
bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
|
|
mLabelGlossy->setVisible(show_shinyctrls);
|
|
mGlossyCtrl->setVisible(show_shinyctrls);
|
|
mLabelEnvironment->setVisible(show_shinyctrls);
|
|
mEnvironmentCtrl->setVisible(show_shinyctrls);
|
|
mLabelShinyColor->setVisible(show_shinyctrls);
|
|
mShinyColorSwatch->setVisible(show_shinyctrls);
|
|
}
|
|
|
|
void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_combobox)
|
|
{
|
|
LLTextureCtrl* texture_ctrl = mBumpyTextureCtrl;
|
|
LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
|
|
LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
|
|
LLComboBox* comboBumpy = mComboBumpy;
|
|
if (!comboBumpy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (mess_with_combobox)
|
|
{
|
|
LLTextureCtrl* texture_ctrl = mBumpyTextureCtrl;
|
|
LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
|
|
LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
|
|
|
|
if (!bumpy_texture_ID.isNull() && is_setting_texture)
|
|
{
|
|
if (!comboBumpy->itemExists(USE_TEXTURE))
|
|
{
|
|
comboBumpy->add(USE_TEXTURE);
|
|
}
|
|
comboBumpy->setSimple(USE_TEXTURE);
|
|
}
|
|
else
|
|
{
|
|
if (comboBumpy->itemExists(USE_TEXTURE))
|
|
{
|
|
comboBumpy->remove(BUMPY_TEXTURE);
|
|
comboBumpy->selectFirstItem();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLPanelFace::updateAlphaControls()
|
|
{
|
|
LLComboBox* comboAlphaMode = mComboAlpha;
|
|
if (!comboAlphaMode)
|
|
{
|
|
return;
|
|
}
|
|
U32 alpha_value = comboAlphaMode->getCurrentIndex();
|
|
bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
|
|
|
|
LLComboBox* combobox_matmedia = mComboMatMedia;
|
|
U32 mat_media = MATMEDIA_MATERIAL;
|
|
if (combobox_matmedia)
|
|
{
|
|
mat_media = combobox_matmedia->getCurrentIndex();
|
|
}
|
|
|
|
LLComboBox* combobox_mattype = mComboMatType;
|
|
U32 mat_type = MATTYPE_DIFFUSE;
|
|
if (combobox_mattype)
|
|
{
|
|
mat_type = combobox_mattype->getCurrentIndex();
|
|
}
|
|
|
|
show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL);
|
|
show_alphactrls = show_alphactrls && (mat_type == MATTYPE_DIFFUSE);
|
|
|
|
mLabelMaskCutoff->setVisible(show_alphactrls);
|
|
mCtrlMaskCutoff->setVisible(show_alphactrls);
|
|
}
|
|
|
|
void LLPanelFace::onCommitAlphaMode()
|
|
{
|
|
updateAlphaControls();
|
|
LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode());
|
|
}
|
|
|
|
// static
|
|
BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
|
|
{
|
|
BOOL accept = TRUE;
|
|
for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
LLViewerObject* obj = node->getObject();
|
|
if(!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
|
|
{
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
return accept;
|
|
}
|
|
|
|
void LLPanelFace::onCommitTexture( const LLSD& data )
|
|
{
|
|
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
|
|
sendTexture();
|
|
}
|
|
|
|
void LLPanelFace::onCancelTexture(const LLSD& data)
|
|
{
|
|
LLSelectMgr::getInstance()->selectionRevertTextures();
|
|
}
|
|
|
|
void LLPanelFace::onSelectTexture(const LLSD& data)
|
|
{
|
|
LLSelectMgr::getInstance()->saveSelectedObjectTextures();
|
|
sendTexture();
|
|
|
|
LLGLenum image_format;
|
|
bool identical_image_format = false;
|
|
LLSelectedTE::getImageFormat(image_format, identical_image_format);
|
|
|
|
LLCtrlSelectionInterface* combobox_alphamode =
|
|
mComboAlpha;
|
|
|
|
U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
|
|
if (combobox_alphamode)
|
|
{
|
|
switch (image_format)
|
|
{
|
|
case GL_RGBA:
|
|
case GL_ALPHA:
|
|
{
|
|
alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
|
|
}
|
|
break;
|
|
|
|
case GL_RGB: break;
|
|
default:
|
|
{
|
|
llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl;
|
|
}
|
|
break;
|
|
}
|
|
|
|
combobox_alphamode->selectNthItem(alpha_mode);
|
|
}
|
|
LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode());
|
|
}
|
|
|
|
void LLPanelFace::onCloseTexturePicker(const LLSD& data)
|
|
{
|
|
LL_DEBUGS("Materials") << data << LL_ENDL;
|
|
updateUI();
|
|
}
|
|
|
|
void LLPanelFace::onCommitSpecularTexture( const LLSD& data )
|
|
{
|
|
LL_DEBUGS("Materials") << data << LL_ENDL;
|
|
sendShiny(SHINY_TEXTURE);
|
|
}
|
|
|
|
void LLPanelFace::onCommitNormalTexture( const LLSD& data )
|
|
{
|
|
LL_DEBUGS("Materials") << data << LL_ENDL;
|
|
LLUUID nmap_id = getCurrentNormalMap();
|
|
sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
|
|
}
|
|
|
|
void LLPanelFace::onCancelSpecularTexture(const LLSD& data)
|
|
{
|
|
U8 shiny = 0;
|
|
bool identical_shiny = false;
|
|
LLSelectedTE::getShiny(shiny, identical_shiny);
|
|
LLUUID spec_map_id = mShinyTextureCtrl->getImageAssetID();
|
|
shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE;
|
|
sendShiny(shiny);
|
|
}
|
|
|
|
void LLPanelFace::onCancelNormalTexture(const LLSD& data)
|
|
{
|
|
U8 bumpy = 0;
|
|
bool identical_bumpy = false;
|
|
LLSelectedTE::getBumpmap(bumpy, identical_bumpy);
|
|
sendBump(bumpy);
|
|
}
|
|
|
|
void LLPanelFace::onSelectSpecularTexture(const LLSD& data)
|
|
{
|
|
LL_DEBUGS("Materials") << data << LL_ENDL;
|
|
sendShiny(SHINY_TEXTURE);
|
|
}
|
|
|
|
void LLPanelFace::onSelectNormalTexture(const LLSD& data)
|
|
{
|
|
LL_DEBUGS("Materials") << data << LL_ENDL;
|
|
LLUUID nmap_id = getCurrentNormalMap();
|
|
sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
|
|
}
|
|
|
|
void LLPanelFace::onCommitMaterialBumpyScaleX(const LLSD& value)
|
|
{
|
|
F32 bumpy_scale_u = value.asReal();
|
|
if (isIdenticalPlanarTexgen())
|
|
{
|
|
bumpy_scale_u *= 0.5f;
|
|
}
|
|
LLSelectedTEMaterial::setNormalRepeatX(this, bumpy_scale_u);
|
|
}
|
|
|
|
void LLPanelFace::onCommitMaterialBumpyScaleY(const LLSD& value)
|
|
{
|
|
F32 bumpy_scale_v = value.asReal();
|
|
if (isIdenticalPlanarTexgen())
|
|
{
|
|
bumpy_scale_v *= 0.5f;
|
|
}
|
|
LLSelectedTEMaterial::setNormalRepeatY(this, bumpy_scale_v);
|
|
}
|
|
|
|
void LLPanelFace::onCommitMaterialShinyScaleX(const LLSD& value)
|
|
{
|
|
F32 shiny_scale_u = value.asReal();
|
|
if (isIdenticalPlanarTexgen())
|
|
{
|
|
shiny_scale_u *= 0.5f;
|
|
}
|
|
LLSelectedTEMaterial::setSpecularRepeatX(this, shiny_scale_u);
|
|
}
|
|
|
|
void LLPanelFace::onCommitMaterialShinyScaleY(const LLSD& value)
|
|
{
|
|
F32 shiny_scale_v = value.asReal();
|
|
if (isIdenticalPlanarTexgen())
|
|
{
|
|
shiny_scale_v *= 0.5f;
|
|
}
|
|
LLSelectedTEMaterial::setSpecularRepeatY(this, shiny_scale_v);
|
|
}
|
|
|
|
void LLPanelFace::onCommitMaterialBumpyRot(const LLSD& value)
|
|
{
|
|
LLSelectedTEMaterial::setNormalRotation(this, value.asReal() * DEG_TO_RAD);
|
|
}
|
|
|
|
void LLPanelFace::onCommitMaterialShinyRot(const LLSD& value)
|
|
{
|
|
LLSelectedTEMaterial::setSpecularRotation(this, value.asReal() * DEG_TO_RAD);
|
|
}
|
|
|
|
void LLPanelFace::onCommitTextureInfo()
|
|
{
|
|
sendTextureInfo();
|
|
// <FS:CR> Materials alignment
|
|
if (gSavedSettings.getBOOL("FSSynchronizeTextureMaps"))
|
|
{
|
|
alignMaterialsProperties();
|
|
}
|
|
// </FS:CR>
|
|
}
|
|
|
|
// Commit the number of repeats per meter
|
|
void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* repeats_ctrl)
|
|
{
|
|
LLComboBox* combo_matmedia = mComboMatMedia;
|
|
LLComboBox* combo_mattype = mComboMatType;
|
|
|
|
U32 materials_media = combo_matmedia->getCurrentIndex();
|
|
|
|
|
|
U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? combo_mattype->getCurrentIndex() : 0;
|
|
F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
|
|
|
|
F32 obj_scale_s = 1.0f;
|
|
F32 obj_scale_t = 1.0f;
|
|
|
|
bool identical_scale_s = false;
|
|
bool identical_scale_t = false;
|
|
|
|
LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s);
|
|
LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t);
|
|
|
|
switch (material_type)
|
|
{
|
|
case MATTYPE_DIFFUSE:
|
|
{
|
|
LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
|
|
}
|
|
break;
|
|
|
|
case MATTYPE_NORMAL:
|
|
{
|
|
LLUICtrl* bumpy_scale_u = mBumpyScaleU;
|
|
LLUICtrl* bumpy_scale_v = mBumpyScaleV;
|
|
|
|
bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
|
|
bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
|
|
|
|
LLSelectedTEMaterial::setNormalRepeatX(this,obj_scale_s * repeats_per_meter);
|
|
LLSelectedTEMaterial::setNormalRepeatY(this,obj_scale_t * repeats_per_meter);
|
|
}
|
|
break;
|
|
|
|
case MATTYPE_SPECULAR:
|
|
{
|
|
LLUICtrl* shiny_scale_u = mShinyScaleU;
|
|
LLUICtrl* shiny_scale_v = mShinyScaleV;
|
|
|
|
shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
|
|
shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
|
|
|
|
LLSelectedTEMaterial::setSpecularRepeatX(this,obj_scale_s * repeats_per_meter);
|
|
LLSelectedTEMaterial::setSpecularRepeatY(this,obj_scale_t * repeats_per_meter);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
llassert(false);
|
|
break;
|
|
}
|
|
}
|
|
|
|
struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
|
|
{
|
|
virtual bool apply(LLViewerObject* object, S32 te)
|
|
{
|
|
viewer_media_t pMediaImpl;
|
|
|
|
const LLTextureEntry* tep = object->getTE(te);
|
|
const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
|
|
if ( mep )
|
|
{
|
|
pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
|
|
}
|
|
|
|
if ( pMediaImpl.isNull())
|
|
{
|
|
// If we didn't find face media for this face, check whether this face is showing parcel media.
|
|
pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
|
|
}
|
|
|
|
if ( pMediaImpl.notNull())
|
|
{
|
|
LLPluginClassMedia *media = pMediaImpl->getMediaPlugin();
|
|
if(media)
|
|
{
|
|
S32 media_width = media->getWidth();
|
|
S32 media_height = media->getHeight();
|
|
S32 texture_width = media->getTextureWidth();
|
|
S32 texture_height = media->getTextureHeight();
|
|
F32 scale_s = (F32)media_width / (F32)texture_width;
|
|
F32 scale_t = (F32)media_height / (F32)texture_height;
|
|
|
|
// set scale and adjust offset
|
|
object->setTEScaleS( te, scale_s );
|
|
object->setTEScaleT( te, scale_t ); // don't need to flip Y anymore since QT does this for us now.
|
|
object->setTEOffsetS( te, -( 1.0f - scale_s ) / 2.0f );
|
|
object->setTEOffsetT( te, -( 1.0f - scale_t ) / 2.0f );
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
};
|
|
|
|
void LLPanelFace::onClickAutoFix()
|
|
{
|
|
LLPanelFaceSetMediaFunctor setfunc;
|
|
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
|
|
|
|
LLPanelFaceSendFunctor sendfunc;
|
|
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
|
|
}
|
|
|
|
|
|
|
|
// TODO: I don't know who put these in or what these are for???
|
|
void LLPanelFace::setMediaURL(const std::string& url)
|
|
{
|
|
}
|
|
void LLPanelFace::setMediaType(const std::string& mime_type)
|
|
{
|
|
}
|
|
|
|
void LLPanelFace::onCommitPlanarAlign()
|
|
{
|
|
getState();
|
|
sendTextureInfo();
|
|
}
|
|
|
|
void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
|
|
{
|
|
LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL;
|
|
LLComboBox* combo_mattype = mComboMatType;
|
|
if (!combo_mattype)
|
|
{
|
|
return;
|
|
}
|
|
U32 mattype = combo_mattype->getCurrentIndex();
|
|
LLTextureCtrl* texture_ctrl = mTextureCtrl;
|
|
switch (mattype)
|
|
{
|
|
case MATTYPE_SPECULAR:
|
|
texture_ctrl = mShinyTextureCtrl;
|
|
break;
|
|
case MATTYPE_NORMAL:
|
|
texture_ctrl = mBumpyTextureCtrl;
|
|
break;
|
|
// no default needed
|
|
}
|
|
if (texture_ctrl)
|
|
{
|
|
LLUUID obj_owner_id;
|
|
std::string obj_owner_name;
|
|
LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name);
|
|
|
|
LLSaleInfo sale_info;
|
|
LLSelectMgr::instance().selectGetSaleInfo(sale_info);
|
|
|
|
bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture?
|
|
bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture?
|
|
bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent?
|
|
bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale?
|
|
|
|
if (can_copy && can_transfer)
|
|
{
|
|
texture_ctrl->setCanApply(true, true);
|
|
return;
|
|
}
|
|
|
|
// if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale
|
|
texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale);
|
|
|
|
if (gSavedSettings.getBOOL("ApplyTextureImmediately"))
|
|
{
|
|
LLNotificationsUtil::add("LivePreviewUnavailable");
|
|
}
|
|
}
|
|
}
|
|
|
|
bool LLPanelFace::isIdenticalPlanarTexgen()
|
|
{
|
|
LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
|
|
bool identical_texgen = false;
|
|
LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
|
|
return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face)
|
|
{
|
|
struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor<LLFace *>
|
|
{
|
|
LLFace* get(LLViewerObject* object, S32 te)
|
|
{
|
|
return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
|
|
}
|
|
} get_te_face_func;
|
|
identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return);
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face)
|
|
{
|
|
LLGLenum image_format;
|
|
struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor<LLGLenum>
|
|
{
|
|
LLGLenum get(LLViewerObject* object, S32 te_index)
|
|
{
|
|
LLViewerTexture* image = object->getTEImage(te_index);
|
|
return image ? image->getPrimaryFormat() : GL_RGB;
|
|
}
|
|
} get_glenum;
|
|
identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format);
|
|
image_format_to_return = image_format;
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
|
|
{
|
|
struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor<LLUUID>
|
|
{
|
|
LLUUID get(LLViewerObject* object, S32 te_index)
|
|
{
|
|
LLUUID id;
|
|
LLViewerTexture* image = object->getTEImage(te_index);
|
|
if (image)
|
|
{
|
|
id = image->getID();
|
|
}
|
|
|
|
if (!id.isNull() && LLViewerMedia::textureHasMedia(id))
|
|
{
|
|
LLTextureEntry *te = object->getTE(te_index);
|
|
if (te)
|
|
{
|
|
LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL;
|
|
if(!tex)
|
|
{
|
|
tex = LLViewerFetchedTexture::sDefaultImagep;
|
|
}
|
|
if (tex)
|
|
{
|
|
id = tex->getID();
|
|
}
|
|
}
|
|
}
|
|
return id;
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material)
|
|
{
|
|
struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr>
|
|
{
|
|
LLMaterialPtr get(LLViewerObject* object, S32 te_index)
|
|
{
|
|
return object->getTE(te_index)->getMaterialParams();
|
|
}
|
|
} func;
|
|
identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr);
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool& identical)
|
|
{
|
|
struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
|
|
U32 s_axis = VX;
|
|
U32 t_axis = VY;
|
|
F32 repeats_s = 1.0f;
|
|
F32 repeats_t = 1.0f;
|
|
if (mat)
|
|
{
|
|
mat->getSpecularRepeat(repeats_s, repeats_t);
|
|
repeats_s /= object->getScale().mV[s_axis];
|
|
repeats_t /= object->getScale().mV[t_axis];
|
|
}
|
|
return llmax(repeats_s, repeats_t);
|
|
}
|
|
|
|
} max_spec_repeats_func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats);
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& identical)
|
|
{
|
|
struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
|
|
U32 s_axis = VX;
|
|
U32 t_axis = VY;
|
|
F32 repeats_s = 1.0f;
|
|
F32 repeats_t = 1.0f;
|
|
if (mat)
|
|
{
|
|
mat->getNormalRepeat(repeats_s, repeats_t);
|
|
repeats_s /= object->getScale().mV[s_axis];
|
|
repeats_t /= object->getScale().mV[t_axis];
|
|
}
|
|
return llmax(repeats_s, repeats_t);
|
|
}
|
|
|
|
} max_norm_repeats_func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats);
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha)
|
|
{
|
|
struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor<U8>
|
|
{
|
|
LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {}
|
|
LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {}
|
|
virtual ~LLSelectedTEGetDiffuseAlphaMode() {}
|
|
|
|
U8 get(LLViewerObject* object, S32 face)
|
|
{
|
|
U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
|
|
|
|
LLTextureEntry* tep = object->getTE(face);
|
|
if (tep)
|
|
{
|
|
LLMaterial* mat = tep->getMaterialParams().get();
|
|
if (mat)
|
|
{
|
|
diffuse_mode = mat->getDiffuseAlphaMode();
|
|
}
|
|
}
|
|
|
|
return diffuse_mode;
|
|
}
|
|
bool _isAlpha; // whether or not the diffuse texture selected contains alpha information
|
|
} get_diff_mode(diffuse_texture_has_alpha);
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode);
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical)
|
|
{
|
|
struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
U32 s_axis = VX;
|
|
U32 t_axis = VY;
|
|
LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
|
|
return object->getScale().mV[s_axis];
|
|
}
|
|
|
|
} scale_s_func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s );
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical)
|
|
{
|
|
struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
U32 s_axis = VX;
|
|
U32 t_axis = VY;
|
|
LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
|
|
return object->getScale().mV[t_axis];
|
|
}
|
|
|
|
} scale_t_func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t );
|
|
}
|
|
|
|
void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identical)
|
|
{
|
|
struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
U32 s_axis = VX;
|
|
U32 t_axis = VY;
|
|
LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
|
|
F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis];
|
|
F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis];
|
|
return llmax(repeats_s, repeats_t);
|
|
}
|
|
|
|
} max_diff_repeats_func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );
|
|
}
|
|
|
|
static LLSD textures;
|
|
|
|
void LLPanelFace::onClickCopy()
|
|
{
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
|
|
if(!objectp)
|
|
{
|
|
objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
|
|
if (!objectp)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
S32 te_count = objectp->getNumFaces();
|
|
textures.clear();
|
|
for (S32 i = 0; i < te_count; i++)
|
|
{
|
|
LLSD tex_params = objectp->getTE(i)->asLLSD();
|
|
LLInventoryItem* itemp = gInventory.getItem(objectp->getTE(i)->getID());
|
|
LLUUID tex = tex_params["imageid"];
|
|
tex_params["imageid"] = LLUUID::null;
|
|
//gSavedPerAccountSettings.setLLSD("Image.Settings", tex_params);
|
|
if (itemp)
|
|
{
|
|
LLPermissions perms = itemp->getPermissions();
|
|
//full perms
|
|
if (perms.getMaskOwner() & PERM_ITEM_UNRESTRICTED)
|
|
{
|
|
tex_params["imageid"] = tex;
|
|
}
|
|
}
|
|
llinfos << "Copying params on face " << i << "." << llendl;
|
|
textures.append(tex_params);
|
|
}
|
|
}
|
|
|
|
void LLPanelFace::onClickPaste()
|
|
{
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
|
|
if(!objectp)
|
|
{
|
|
objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
|
|
if (!objectp)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
LLMessageSystem* msg = gMessageSystem;
|
|
msg->newMessageFast(_PREHASH_ObjectImage);
|
|
msg->nextBlockFast(_PREHASH_AgentData);
|
|
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
|
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
|
|
|
msg->nextBlockFast(_PREHASH_ObjectData);
|
|
msg->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
|
|
msg->addStringFast(_PREHASH_MediaURL, NULL);
|
|
|
|
LLPrimitive obj;
|
|
obj.setNumTEs(U8(textures.size()));
|
|
|
|
for (int i = 0; i < textures.size() && i < objectp->getNumTEs(); i++)
|
|
{
|
|
llinfos << "Pasting params on face " << i << "." << llendl;
|
|
LLSD cur_tex = objectp->getTE(i)->asLLSD();
|
|
if (textures[i]["imageid"].asUUID() == LLUUID::null)
|
|
textures[i]["imageid"] = cur_tex["imageid"];
|
|
LLTextureEntry tex;
|
|
tex.fromLLSD(textures[i]);
|
|
obj.setTE(U8(i), tex);
|
|
}
|
|
|
|
obj.packTEMessage(gMessageSystem);
|
|
|
|
msg->sendReliable(gAgent.getRegion()->getHost());
|
|
}
|
|
|
|
// <FS:CR> Materials alignment
|
|
void LLPanelFace::onClickMapsSync()
|
|
{
|
|
getState();
|
|
if (gSavedSettings.getBOOL("FSSynchronizeTextureMaps"))
|
|
{
|
|
alignMaterialsProperties();
|
|
}
|
|
}
|
|
|
|
void LLPanelFace::alignMaterialsProperties()
|
|
{
|
|
F32 tex_scale_u = mCtrlTexScaleU->getValue().asReal();
|
|
F32 tex_scale_v = mCtrlTexScaleV->getValue().asReal();
|
|
F32 tex_offset_u = mCtrlTexOffsetU->getValue().asReal();
|
|
F32 tex_offset_v = mCtrlTexOffsetV->getValue().asReal();
|
|
F32 tex_rot = mCtrlTexRot->getValue().asReal();
|
|
|
|
mShinyScaleU->setValue(tex_scale_u);
|
|
mShinyScaleV->setValue(tex_scale_v);
|
|
mShinyOffsetU->setValue(tex_offset_u);
|
|
mShinyOffsetV->setValue(tex_offset_v);
|
|
mShinyRot->setValue(tex_rot);
|
|
|
|
LLSelectedTEMaterial::setSpecularRepeatX(this, tex_scale_u);
|
|
LLSelectedTEMaterial::setSpecularRepeatY(this, tex_scale_v);
|
|
LLSelectedTEMaterial::setSpecularOffsetX(this, tex_offset_u);
|
|
LLSelectedTEMaterial::setSpecularOffsetY(this, tex_offset_v);
|
|
LLSelectedTEMaterial::setSpecularRotation(this, tex_rot * DEG_TO_RAD);
|
|
|
|
mBumpyScaleU->setValue(tex_scale_u);
|
|
mBumpyScaleV->setValue(tex_scale_v);
|
|
mBumpyOffsetU->setValue(tex_offset_u);
|
|
mBumpyOffsetV->setValue(tex_offset_v);
|
|
mBumpyRot->setValue(tex_rot);
|
|
|
|
LLSelectedTEMaterial::setNormalRepeatX(this, tex_scale_u);
|
|
LLSelectedTEMaterial::setNormalRepeatY(this, tex_scale_v);
|
|
LLSelectedTEMaterial::setNormalOffsetX(this, tex_offset_u);
|
|
LLSelectedTEMaterial::setNormalOffsetY(this, tex_offset_v);
|
|
LLSelectedTEMaterial::setNormalRotation(this, tex_rot * DEG_TO_RAD);
|
|
}
|
|
|
|
// <FS:CR> FIRE-11407 - Flip buttons
|
|
void LLPanelFace::onCommitFlip(bool flip_x)
|
|
{
|
|
S32 mattype(mComboMatType->getCurrentIndex());
|
|
LLUICtrl* spinner = NULL;
|
|
switch (mattype)
|
|
{
|
|
case MATTYPE_DIFFUSE:
|
|
spinner = flip_x ? mCtrlTexScaleU : mCtrlTexScaleV;
|
|
break;
|
|
case MATTYPE_NORMAL:
|
|
spinner = flip_x ? mBumpyScaleU : mBumpyScaleV;
|
|
break;
|
|
case MATTYPE_SPECULAR:
|
|
spinner = flip_x ? mShinyScaleU : mShinyScaleV;
|
|
break;
|
|
default:
|
|
//llassert(mattype);
|
|
return;
|
|
}
|
|
|
|
if (spinner)
|
|
{
|
|
F32 value = -(spinner->getValue().asReal());
|
|
spinner->setValue(value);
|
|
|
|
switch (mattype)
|
|
{
|
|
case MATTYPE_DIFFUSE:
|
|
sendTextureInfo();
|
|
if (gSavedSettings.getBOOL("FSSyncronizeTextureMaps"))
|
|
{
|
|
alignMaterialsProperties();
|
|
}
|
|
break;
|
|
case MATTYPE_NORMAL:
|
|
if (flip_x)
|
|
LLSelectedTEMaterial::setNormalRepeatX(this, value);
|
|
else
|
|
LLSelectedTEMaterial::setNormalRepeatY(this, value);
|
|
break;
|
|
case MATTYPE_SPECULAR:
|
|
if (flip_x)
|
|
LLSelectedTEMaterial::setSpecularRepeatX(this, value);
|
|
else
|
|
LLSelectedTEMaterial::setSpecularRepeatY(this, value);
|
|
break;
|
|
default:
|
|
//llassert(mattype);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
// </FS:CR>
|