1848 lines
60 KiB
C++
1848 lines
60 KiB
C++
/**
|
|
* @file llpanelface.cpp
|
|
* @brief Panel in the tools floater for editing face textures, colors, etc.
|
|
*
|
|
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2010, Linden Research, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License only.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
// 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 "llagentdata.h"
|
|
#include "llbutton.h"
|
|
#include "llcheckboxctrl.h"
|
|
#include "llcolorswatch.h"
|
|
#include "llcombobox.h"
|
|
#include "lldrawpoolbump.h"
|
|
#include "llface.h"
|
|
#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 "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"
|
|
|
|
//
|
|
// 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
|
|
|
|
//
|
|
// Methods
|
|
//
|
|
|
|
BOOL LLPanelFace::postBuild()
|
|
{
|
|
childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
|
|
childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
|
|
childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this);
|
|
childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
|
|
childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
|
|
childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
|
|
childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this);
|
|
childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
|
|
childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
|
|
childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
|
|
childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("environment",&LLPanelFace::onCommitMaterial, this);
|
|
childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterial, this);
|
|
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
|
|
|
|
LLRect rect = this->getRect();
|
|
LLTextureCtrl* mTextureCtrl;
|
|
LLTextureCtrl* mShinyTextureCtrl;
|
|
LLTextureCtrl* mBumpyTextureCtrl;
|
|
LLColorSwatchCtrl* mColorSwatch;
|
|
LLColorSwatchCtrl* mShinyColorSwatch;
|
|
|
|
LLComboBox* mComboTexGen;
|
|
LLComboBox* mComboMatMedia;
|
|
LLComboBox* mComboMatType;
|
|
|
|
LLCheckBoxCtrl *mCheckFullbright;
|
|
|
|
LLTextBox* mLabelColorTransp;
|
|
LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha
|
|
|
|
LLSpinCtrl* mCtrlGlow;
|
|
|
|
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->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( "DefaultObjectTexture" )));
|
|
mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitMaterialTexture, this, _2) );
|
|
mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelMaterialTexture, this, _2) );
|
|
mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectMaterialTexture, 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( "DefaultObjectTexture" )));
|
|
mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitMaterialTexture, this, _2) );
|
|
mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelMaterialTexture, this, _2) );
|
|
mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectMaterialTexture, 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::onCommitColor, this, _2));
|
|
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::onCommitAlpha, this, _2));
|
|
mCtrlColorTransp->setPrecision(0);
|
|
mCtrlColorTransp->setFollowsTop();
|
|
mCtrlColorTransp->setFollowsLeft();
|
|
}
|
|
|
|
mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
|
|
if (mCheckFullbright)
|
|
{
|
|
mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright, this);
|
|
}
|
|
|
|
mComboTexGen = getChild<LLComboBox>("combobox texgen");
|
|
if(mComboTexGen)
|
|
{
|
|
mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen, this);
|
|
mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
|
|
}
|
|
|
|
mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
|
|
if(mComboMatMedia)
|
|
{
|
|
mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
|
|
mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
|
|
}
|
|
|
|
mComboMatType = getChild<LLComboBox>("combobox mattype");
|
|
if(mComboMatType)
|
|
{
|
|
mComboMatType->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
|
|
mComboMatType->selectNthItem(MATTYPE_DIFFUSE);
|
|
}
|
|
|
|
mCtrlGlow = getChild<LLSpinCtrl>("glow");
|
|
if(mCtrlGlow)
|
|
{
|
|
mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
|
|
}
|
|
|
|
|
|
clearCtrls();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LLPanelFace::LLPanelFace()
|
|
: LLPanel(),
|
|
mMaterialID(LLMaterialID::null),
|
|
mMaterial(LLMaterialPtr()),
|
|
mIsAlpha(false),
|
|
mUpdateInFlight(false),
|
|
mUpdatePending(false)
|
|
{
|
|
}
|
|
|
|
|
|
LLPanelFace::~LLPanelFace()
|
|
{
|
|
// Children all cleaned up by default view destructor.
|
|
}
|
|
|
|
|
|
void LLPanelFace::sendTexture()
|
|
{
|
|
LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("texture control");
|
|
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()
|
|
{
|
|
LLComboBox* mComboBumpiness = getChild<LLComboBox>("combobox bumpiness");
|
|
if(!mComboBumpiness)return;
|
|
U8 bump = (U8) mComboBumpiness->getCurrentIndex() & TEM_BUMP_MASK;
|
|
LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
|
|
}
|
|
|
|
void LLPanelFace::sendTexGen()
|
|
{
|
|
LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
|
|
if(!mComboTexGen)return;
|
|
U8 tex_gen = (U8) mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT;
|
|
LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen );
|
|
}
|
|
|
|
void LLPanelFace::sendShiny()
|
|
{
|
|
LLComboBox* mComboShininess = getChild<LLComboBox>("combobox shininess");
|
|
if(!mComboShininess)return;
|
|
U8 shiny = (U8) mComboShininess->getCurrentIndex() & TEM_SHINY_MASK;
|
|
LLSelectMgr::getInstance()->selectionSetShiny( shiny );
|
|
}
|
|
|
|
void LLPanelFace::sendFullbright()
|
|
{
|
|
LLCheckBoxCtrl* mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
|
|
if(!mCheckFullbright)return;
|
|
U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0;
|
|
LLSelectMgr::getInstance()->selectionSetFullbright( fullbright );
|
|
}
|
|
|
|
void LLPanelFace::sendColor()
|
|
{
|
|
|
|
LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
|
|
if(!mColorSwatch)return;
|
|
LLColor4 color = mColorSwatch->get();
|
|
|
|
LLSelectMgr::getInstance()->selectionSetColorOnly( color );
|
|
}
|
|
|
|
void LLPanelFace::sendAlpha()
|
|
{
|
|
LLSpinCtrl* mCtrlColorTransp = getChild<LLSpinCtrl>("ColorTrans");
|
|
if(!mCtrlColorTransp)return;
|
|
F32 alpha = (100.f - mCtrlColorTransp->get()) / 100.f;
|
|
|
|
LLSelectMgr::getInstance()->selectionSetAlphaOnly( alpha );
|
|
}
|
|
|
|
|
|
void LLPanelFace::sendGlow()
|
|
{
|
|
LLSpinCtrl* mCtrlGlow = getChild<LLSpinCtrl>("glow");
|
|
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->getChild<LLSpinCtrl>("TexScaleU");
|
|
LLSpinCtrl* ctrlTexScaleT = mPanel->getChild<LLSpinCtrl>("TexScaleV");
|
|
LLSpinCtrl* ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU");
|
|
LLSpinCtrl* ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV");
|
|
LLSpinCtrl* ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot");
|
|
LLComboBox* comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
|
|
llassert(comboTexGen);
|
|
llassert(object);
|
|
|
|
if (ctrlTexScaleS)
|
|
{
|
|
valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative();
|
|
if (valid)
|
|
{
|
|
value = ctrlTexScaleS->get();
|
|
//if( checkFlipScaleS->get() )
|
|
//{
|
|
// value = -value;
|
|
//}
|
|
if (comboTexGen &&
|
|
comboTexGen->getCurrentIndex() == 1)
|
|
{
|
|
value *= 0.5f;
|
|
}
|
|
object->setTEScaleS( te, value );
|
|
}
|
|
}
|
|
|
|
if (ctrlTexScaleT)
|
|
{
|
|
valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative();
|
|
if (valid)
|
|
{
|
|
value = ctrlTexScaleT->get();
|
|
//if( checkFlipScaleT->get() )
|
|
//{
|
|
// value = -value;
|
|
//}
|
|
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)childGetValue("checkbox planar align").asBoolean())
|
|
{
|
|
struct f1 : public LLSelectedTEGetFunctor<LLFace *>
|
|
{
|
|
LLFace* get(LLViewerObject* object, S32 te)
|
|
{
|
|
return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
|
|
}
|
|
} get_last_face_func;
|
|
LLFace* last_face;
|
|
LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_last_face_func, last_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()
|
|
{
|
|
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
|
|
getChildView("button align")->setEnabled(editable);
|
|
|
|
LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
|
|
if (combobox_matmedia)
|
|
{
|
|
if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL)
|
|
{
|
|
combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
llwarns << "failed getChild for 'combobox matmedia'" << llendl;
|
|
}
|
|
getChildView("combobox matmedia")->setEnabled(editable);
|
|
|
|
LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype");
|
|
if (combobox_mattype)
|
|
{
|
|
if (combobox_mattype->getCurrentIndex() < MATTYPE_DIFFUSE)
|
|
{
|
|
combobox_mattype->selectNthItem(MATTYPE_DIFFUSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
llwarns << "failed getChild for 'combobox mattype'" << llendl;
|
|
}
|
|
getChildView("combobox mattype")->setEnabled(editable);
|
|
onCommitMaterialsMedia(NULL, this);
|
|
|
|
//if ( LLMediaEngine::getInstance()->getMediaRenderer () )
|
|
// if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
|
|
// {
|
|
//
|
|
// //mLabelTexAutoFix->setEnabled ( editable );
|
|
//
|
|
// //mBtnAutoFix->setEnabled ( editable );
|
|
// }
|
|
|
|
bool identical;
|
|
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
|
|
LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
|
|
LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
|
|
|
|
// Texture
|
|
{
|
|
LLUUID id;
|
|
struct f1 : 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 );
|
|
|
|
mIsAlpha = FALSE;
|
|
LLGLenum image_format;
|
|
struct f2 : public LLSelectedTEGetFunctor<LLGLenum>
|
|
{
|
|
LLGLenum get(LLViewerObject* object, S32 te_index)
|
|
{
|
|
LLGLenum image_format = GL_RGB;
|
|
|
|
LLViewerTexture* image = object->getTEImage(te_index);
|
|
if (image) image_format = image->getPrimaryFormat();
|
|
return image_format;
|
|
}
|
|
} func2;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func2, image_format );
|
|
mIsAlpha = image_format != GL_RGB;
|
|
|
|
if(LLViewerMedia::textureHasMedia(id))
|
|
{
|
|
getChildView("button align")->setEnabled(editable);
|
|
}
|
|
|
|
{
|
|
// Default alpha mode to None if texture has no alpha, or Alpha Blending if present
|
|
// Will be overridden later if a material is present for this face
|
|
S32 default_alpha = ALPHAMODE_NONE;
|
|
if (mIsAlpha)
|
|
{
|
|
default_alpha = ALPHAMODE_BLEND;
|
|
}
|
|
LLCtrlSelectionInterface* combobox_alphamode =
|
|
childGetSelectionInterface("combobox alphamode");
|
|
if (combobox_alphamode)
|
|
{
|
|
combobox_alphamode->selectNthItem(default_alpha);
|
|
}
|
|
else
|
|
{
|
|
llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
|
|
}
|
|
updateAlphaControls(getChild<LLComboBox>("combobox alphamode"),this);
|
|
}
|
|
|
|
if (identical)
|
|
{
|
|
// All selected have the same texture
|
|
if(texture_ctrl)
|
|
{
|
|
texture_ctrl->setTentative( FALSE );
|
|
texture_ctrl->setEnabled( editable );
|
|
texture_ctrl->setImageAssetID( id );
|
|
shinytexture_ctrl->setTentative( FALSE );
|
|
shinytexture_ctrl->setEnabled( editable );
|
|
shinytexture_ctrl->setImageAssetID( LLUUID::null );
|
|
bumpytexture_ctrl->setTentative( FALSE );
|
|
bumpytexture_ctrl->setEnabled( editable );
|
|
bumpytexture_ctrl->setImageAssetID( LLUUID::null );
|
|
getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha);
|
|
getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
|
|
getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
|
|
getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(texture_ctrl)
|
|
{
|
|
if( id.isNull() )
|
|
{
|
|
// None selected
|
|
texture_ctrl->setTentative( FALSE );
|
|
texture_ctrl->setEnabled( FALSE );
|
|
texture_ctrl->setImageAssetID( LLUUID::null );
|
|
shinytexture_ctrl->setTentative( FALSE );
|
|
shinytexture_ctrl->setEnabled( FALSE );
|
|
shinytexture_ctrl->setImageAssetID( LLUUID::null );
|
|
bumpytexture_ctrl->setTentative( FALSE );
|
|
bumpytexture_ctrl->setEnabled( FALSE );
|
|
bumpytexture_ctrl->setImageAssetID( LLUUID::null );
|
|
getChildView("combobox alphamode")->setEnabled( FALSE );
|
|
getChildView("label alphamode")->setEnabled( FALSE );
|
|
getChildView("maskcutoff")->setEnabled( FALSE);
|
|
getChildView("label maskcutoff")->setEnabled( FALSE );
|
|
}
|
|
else
|
|
{
|
|
// Tentative: multiple selected with different textures
|
|
texture_ctrl->setTentative( TRUE );
|
|
texture_ctrl->setEnabled( editable );
|
|
texture_ctrl->setImageAssetID( id );
|
|
shinytexture_ctrl->setTentative( TRUE );
|
|
shinytexture_ctrl->setEnabled( editable );
|
|
shinytexture_ctrl->setImageAssetID( LLUUID::null );
|
|
bumpytexture_ctrl->setTentative( TRUE );
|
|
bumpytexture_ctrl->setEnabled( editable );
|
|
bumpytexture_ctrl->setImageAssetID( LLUUID::null );
|
|
getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha);
|
|
getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
|
|
getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
|
|
getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// planar align
|
|
bool align_planar = false;
|
|
bool identical_planar_aligned = false;
|
|
bool is_planar = false;
|
|
{
|
|
LLCheckBoxCtrl* cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");
|
|
align_planar = (cb_planar_align && cb_planar_align->get());
|
|
struct f1 : public LLSelectedTEGetFunctor<bool>
|
|
{
|
|
bool get(LLViewerObject* object, S32 face)
|
|
{
|
|
return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR);
|
|
}
|
|
} func;
|
|
|
|
bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar );
|
|
bool enabled = (editable && texgens_identical && is_planar);
|
|
childSetValue("checkbox planar align", align_planar && enabled);
|
|
childSetEnabled("checkbox planar align", enabled);
|
|
|
|
if (align_planar && enabled)
|
|
{
|
|
struct f2 : public LLSelectedTEGetFunctor<LLFace *>
|
|
{
|
|
LLFace* get(LLViewerObject* object, S32 te)
|
|
{
|
|
return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
|
|
}
|
|
} get_te_face_func;
|
|
LLFace* last_face;
|
|
LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, last_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);
|
|
}
|
|
}
|
|
|
|
// Texture scale
|
|
{
|
|
F32 scale_s = 1.f;
|
|
struct f2 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return object->getTE(face)->mScaleS;
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s );
|
|
identical = align_planar ? identical_planar_aligned : identical;
|
|
getChild<LLUICtrl>("TexScaleU")->setValue(editable ? scale_s : 0);
|
|
getChild<LLUICtrl>("TexScaleU")->setTentative(LLSD((BOOL)(!identical)));
|
|
getChildView("TexScaleU")->setEnabled(editable);
|
|
getChild<LLUICtrl>("shinyScaleU")->setValue(editable ? scale_s : 0);
|
|
getChild<LLUICtrl>("shinyScaleU")->setTentative(LLSD((BOOL)(!identical)));
|
|
getChildView("shinyScaleU")->setEnabled(FALSE);
|
|
getChild<LLUICtrl>("bumpyScaleU")->setValue(editable ? scale_s : 0);
|
|
getChild<LLUICtrl>("bumpyScaleU")->setTentative(LLSD((BOOL)(!identical)));
|
|
getChildView("bumpyScaleU")->setEnabled(FALSE);
|
|
}
|
|
|
|
{
|
|
F32 scale_t = 1.f;
|
|
struct f3 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return object->getTE(face)->mScaleT;
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t );
|
|
identical = align_planar ? identical_planar_aligned : identical;
|
|
|
|
getChild<LLUICtrl>("TexScaleV")->setValue(editable ? scale_t : 0);
|
|
getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD((BOOL)(!identical)));
|
|
getChildView("TexScaleV")->setEnabled(editable);
|
|
getChild<LLUICtrl>("shinyScaleV")->setValue(editable ? scale_t : 0);
|
|
getChild<LLUICtrl>("shinyScaleV")->setTentative(LLSD((BOOL)(!identical)));
|
|
getChildView("shinyScaleV")->setEnabled(FALSE);
|
|
getChild<LLUICtrl>("bumpyScaleV")->setValue(editable ? scale_t : 0);
|
|
getChild<LLUICtrl>("bumpyScaleV")->setTentative(LLSD((BOOL)(!identical)));
|
|
getChildView("bumpyScaleV")->setEnabled(FALSE);
|
|
}
|
|
|
|
// Texture offset
|
|
{
|
|
getChildView("tex offset")->setEnabled(editable);
|
|
F32 offset_s = 0.f;
|
|
struct f4 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return object->getTE(face)->mOffsetS;
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s );
|
|
identical = align_planar ? identical_planar_aligned : identical;
|
|
getChild<LLUICtrl>("TexOffsetU")->setValue(editable ? offset_s : 0);
|
|
getChild<LLUICtrl>("TexOffsetU")->setTentative(!identical);
|
|
getChildView("TexOffsetU")->setEnabled(editable);
|
|
getChild<LLUICtrl>("shinyOffsetU")->setValue(editable ? offset_s : 0);
|
|
getChild<LLUICtrl>("shinyOffsetU")->setTentative(!identical);
|
|
getChildView("shinyOffsetU")->setEnabled(FALSE);
|
|
getChild<LLUICtrl>("bumpyOffsetU")->setValue(editable ? offset_s : 0);
|
|
getChild<LLUICtrl>("bumpyOffsetU")->setTentative(!identical);
|
|
getChildView("bumpyOffsetU")->setEnabled(FALSE);
|
|
}
|
|
|
|
{
|
|
F32 offset_t = 0.f;
|
|
struct f5 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return object->getTE(face)->mOffsetT;
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t );
|
|
identical = align_planar ? identical_planar_aligned : identical;
|
|
getChild<LLUICtrl>("TexOffsetV")->setValue(editable ? offset_t : 0);
|
|
getChild<LLUICtrl>("TexOffsetV")->setTentative(!identical);
|
|
getChildView("TexOffsetV")->setEnabled(editable);
|
|
getChild<LLUICtrl>("shinyOffsetV")->setValue(editable ? offset_t : 0);
|
|
getChild<LLUICtrl>("shinyOffsetV")->setTentative(!identical);
|
|
getChildView("shinyOffsetV")->setEnabled(FALSE);
|
|
getChild<LLUICtrl>("bumpyOffsetV")->setValue(editable ? offset_t : 0);
|
|
getChild<LLUICtrl>("bumpyOffsetV")->setTentative(!identical);
|
|
getChildView("bumpyOffsetV")->setEnabled(FALSE);
|
|
}
|
|
|
|
// Texture rotation
|
|
{
|
|
F32 rotation = 0.f;
|
|
struct f6 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return object->getTE(face)->mRotation;
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation );
|
|
identical = align_planar ? identical_planar_aligned : identical;
|
|
getChild<LLUICtrl>("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0);
|
|
getChild<LLUICtrl>("TexRot")->setTentative(!identical);
|
|
getChildView("TexRot")->setEnabled(editable);
|
|
getChild<LLUICtrl>("shinyRot")->setValue(editable ? rotation * RAD_TO_DEG : 0);
|
|
getChild<LLUICtrl>("shinyRot")->setTentative(!identical);
|
|
getChildView("shinyRot")->setEnabled(FALSE);
|
|
getChild<LLUICtrl>("bumpyRot")->setValue(editable ? rotation * RAD_TO_DEG : 0);
|
|
getChild<LLUICtrl>("bumpyRot")->setTentative(!identical);
|
|
getChildView("bumpyRot")->setEnabled(FALSE);
|
|
}
|
|
|
|
// Color swatch
|
|
{
|
|
getChildView("color label")->setEnabled(editable);
|
|
}
|
|
LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
|
|
LLColor4 color = LLColor4::white;
|
|
if(mColorSwatch)
|
|
{
|
|
struct f7 : public LLSelectedTEGetFunctor<LLColor4>
|
|
{
|
|
LLColor4 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return object->getTE(face)->getColor();
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, color );
|
|
|
|
mColorSwatch->setOriginal(color);
|
|
mColorSwatch->set(color, TRUE);
|
|
|
|
mColorSwatch->setValid(editable);
|
|
mColorSwatch->setEnabled( editable );
|
|
mColorSwatch->setCanApplyImmediately( editable );
|
|
}
|
|
// Color transparency
|
|
{
|
|
getChildView("color trans")->setEnabled(editable);
|
|
}
|
|
|
|
F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
|
|
{
|
|
getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
|
|
getChildView("ColorTrans")->setEnabled(editable);
|
|
}
|
|
|
|
{
|
|
F32 glow = 0.f;
|
|
struct f8 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return object->getTE(face)->getGlow();
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, glow );
|
|
|
|
getChild<LLUICtrl>("glow")->setValue(glow);
|
|
getChildView("glow")->setEnabled(editable);
|
|
getChild<LLUICtrl>("glow")->setTentative(!identical);
|
|
getChildView("glow label")->setEnabled(editable);
|
|
|
|
}
|
|
|
|
// Shiny
|
|
{
|
|
F32 shinyf = 0.f;
|
|
struct f9 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return (F32)(object->getTE(face)->getShiny());
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, shinyf );
|
|
LLCtrlSelectionInterface* combobox_shininess =
|
|
childGetSelectionInterface("combobox shininess");
|
|
if (combobox_shininess)
|
|
{
|
|
combobox_shininess->selectNthItem((S32)shinyf);
|
|
}
|
|
else
|
|
{
|
|
llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl;
|
|
}
|
|
getChildView("combobox shininess")->setEnabled(editable);
|
|
getChild<LLUICtrl>("combobox shininess")->setTentative(!identical);
|
|
getChildView("label shininess")->setEnabled(editable);
|
|
getChildView("glossiness")->setEnabled(editable);
|
|
getChild<LLUICtrl>("glossiness")->setTentative(!identical);
|
|
getChildView("label glossiness")->setEnabled(editable);
|
|
getChildView("environment")->setEnabled(editable);
|
|
getChild<LLUICtrl>("environment")->setTentative(!identical);
|
|
getChildView("label environment")->setEnabled(editable);
|
|
getChildView("shinycolorswatch")->setEnabled(editable);
|
|
getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical);
|
|
getChildView("label shinycolor")->setEnabled(editable);
|
|
}
|
|
|
|
// Bumpy
|
|
{
|
|
F32 bumpf = 0.f;
|
|
struct f10 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return (F32)(object->getTE(face)->getBumpmap());
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, bumpf );
|
|
LLCtrlSelectionInterface* combobox_bumpiness =
|
|
childGetSelectionInterface("combobox bumpiness");
|
|
if (combobox_bumpiness)
|
|
{
|
|
combobox_bumpiness->selectNthItem((S32)bumpf);
|
|
}
|
|
else
|
|
{
|
|
llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
|
|
}
|
|
getChildView("combobox bumpiness")->setEnabled(editable);
|
|
getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical);
|
|
getChildView("label bumpiness")->setEnabled(editable);
|
|
}
|
|
|
|
{
|
|
F32 genf = 0.f;
|
|
struct f11 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return (F32)(object->getTE(face)->getTexGen());
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, genf );
|
|
S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT;
|
|
LLCtrlSelectionInterface* combobox_texgen =
|
|
childGetSelectionInterface("combobox texgen");
|
|
if (combobox_texgen)
|
|
{
|
|
combobox_texgen->selectNthItem(selected_texgen);
|
|
}
|
|
else
|
|
{
|
|
llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl;
|
|
}
|
|
getChildView("combobox texgen")->setEnabled(editable);
|
|
getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);
|
|
getChildView("tex gen")->setEnabled(editable);
|
|
|
|
if (selected_texgen == 1)
|
|
{
|
|
getChild<LLUICtrl>("TexScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() );
|
|
getChild<LLUICtrl>("TexScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() );
|
|
getChild<LLUICtrl>("shinyScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() );
|
|
getChild<LLUICtrl>("shinyScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() );
|
|
getChild<LLUICtrl>("bumpyScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() );
|
|
getChild<LLUICtrl>("bumpyScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() );
|
|
|
|
// EXP-1507 (change label based on the mapping mode)
|
|
getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter"));
|
|
}
|
|
else
|
|
if (selected_texgen == 0) // FIXME: should not be magic numbers
|
|
{
|
|
getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face"));
|
|
}
|
|
}
|
|
|
|
{
|
|
F32 fullbrightf = 0.f;
|
|
struct f12 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
return (F32)(object->getTE(face)->getFullbright());
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf );
|
|
|
|
getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)fullbrightf);
|
|
getChildView("checkbox fullbright")->setEnabled(editable);
|
|
getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical);
|
|
}
|
|
|
|
// Repeats per meter
|
|
{
|
|
F32 repeats = 1.f;
|
|
struct f13 : public LLSelectedTEGetFunctor<F32>
|
|
{
|
|
F32 get(LLViewerObject* object, S32 face)
|
|
{
|
|
U32 s_axis = VX;
|
|
U32 t_axis = VY;
|
|
// BUG: Only repeats along S axis
|
|
// BUG: Only works for boxes.
|
|
LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
|
|
return object->getTE(face)->mScaleS / object->getScale().mV[s_axis];
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats );
|
|
|
|
getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 0);
|
|
getChild<LLUICtrl>("rptctrl")->setTentative(!identical);
|
|
LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
|
|
if (mComboTexGen)
|
|
{
|
|
BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1);
|
|
getChildView("rptctrl")->setEnabled(enabled);
|
|
}
|
|
}
|
|
|
|
// Materials
|
|
{
|
|
mMaterialID = LLMaterialID::null;
|
|
mMaterial.reset();
|
|
struct f1 : public LLSelectedTEGetFunctor<LLMaterialID>
|
|
{
|
|
LLMaterialID get(LLViewerObject* object, S32 te_index)
|
|
{
|
|
LLMaterialID material_id;
|
|
|
|
return object->getTE(te_index)->getMaterialID();
|
|
}
|
|
} func;
|
|
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, mMaterialID );
|
|
llinfos << "Material ID returned: '"
|
|
<< mMaterialID.asString() << "', isNull? "
|
|
<< (mMaterialID.isNull()?"TRUE":"FALSE") << llendl;
|
|
if (!mMaterialID.isNull() && editable)
|
|
{
|
|
llinfos << "Requesting material ID " << mMaterialID.asString() << llendl;
|
|
LLMaterialMgr::getInstance()->get(objectp->getRegion()->getRegionID(),mMaterialID,boost::bind(&LLPanelFace::onMaterialLoaded, this, _1, _2));
|
|
}
|
|
if (mUpdatePending && !mUpdateInFlight)
|
|
{
|
|
// One or more updates are pending, and the
|
|
// previous one has been acknowledged. Send
|
|
// the pending updates.
|
|
updateMaterial();
|
|
}
|
|
}
|
|
|
|
// Set variable values for numeric expressions
|
|
LLCalc* calcp = LLCalc::getInstance();
|
|
calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal());
|
|
calcp->setVar(LLCalc::TEX_V_SCALE, childGetValue("TexScaleV").asReal());
|
|
calcp->setVar(LLCalc::TEX_U_OFFSET, childGetValue("TexOffsetU").asReal());
|
|
calcp->setVar(LLCalc::TEX_V_OFFSET, childGetValue("TexOffsetV").asReal());
|
|
calcp->setVar(LLCalc::TEX_ROTATION, childGetValue("TexRot").asReal());
|
|
calcp->setVar(LLCalc::TEX_TRANSPARENCY, childGetValue("ColorTrans").asReal());
|
|
calcp->setVar(LLCalc::TEX_GLOW, childGetValue("glow").asReal());
|
|
}
|
|
else
|
|
{
|
|
// Disable all UICtrls
|
|
clearCtrls();
|
|
|
|
// Disable non-UICtrls
|
|
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
|
|
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);
|
|
}
|
|
LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
|
|
if(mColorSwatch)
|
|
{
|
|
mColorSwatch->setEnabled( FALSE );
|
|
mColorSwatch->setFallbackImageName("locked_image.j2c" );
|
|
mColorSwatch->setValid(FALSE);
|
|
}
|
|
getChildView("color trans")->setEnabled(FALSE);
|
|
getChildView("rpt")->setEnabled(FALSE);
|
|
getChildView("tex offset")->setEnabled(FALSE);
|
|
getChildView("tex gen")->setEnabled(FALSE);
|
|
getChildView("label shininess")->setEnabled(FALSE);
|
|
getChildView("label bumpiness")->setEnabled(FALSE);
|
|
|
|
getChildView("button align")->setEnabled(FALSE);
|
|
//getChildView("has media")->setEnabled(FALSE);
|
|
//getChildView("media info set")->setEnabled(FALSE);
|
|
|
|
onCommitMaterialsMedia(NULL,this);
|
|
|
|
// 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()
|
|
{
|
|
getState();
|
|
}
|
|
|
|
void LLPanelFace::onMaterialLoaded(const LLMaterialID& material_id, const LLMaterialPtr material)
|
|
{
|
|
mMaterial = material;
|
|
// We've gotten a materials update, so the sim's ready for another.
|
|
mUpdateInFlight = false;
|
|
|
|
// Alpha
|
|
LLCtrlSelectionInterface* combobox_alphamode =
|
|
childGetSelectionInterface("combobox alphamode");
|
|
if (combobox_alphamode)
|
|
{
|
|
combobox_alphamode->selectNthItem(material->getDiffuseAlphaMode());
|
|
}
|
|
else
|
|
{
|
|
llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
|
|
}
|
|
getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff());
|
|
updateAlphaControls(getChild<LLComboBox>("combobox alphamode"),this);
|
|
|
|
// Shiny (specular)
|
|
F32 offset_x, offset_y, repeat_x, repeat_y, rot;
|
|
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
|
|
texture_ctrl->setImageAssetID(material->getSpecularID());
|
|
if (!material->getSpecularID().isNull())
|
|
{
|
|
material->getSpecularOffset(offset_x,offset_y);
|
|
material->getSpecularRepeat(repeat_x,repeat_y);
|
|
rot = material->getSpecularRotation();
|
|
LLCtrlSelectionInterface* combobox_shininess =
|
|
childGetSelectionInterface("combobox shininess");
|
|
if (combobox_shininess)
|
|
{
|
|
combobox_shininess->selectNthItem(SHINY_TEXTURE);
|
|
}
|
|
else
|
|
{
|
|
llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl;
|
|
}
|
|
getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x);
|
|
getChild<LLUICtrl>("shinyScaleV")->setValue(repeat_y);
|
|
getChild<LLUICtrl>("shinyRot")->setValue(rot);
|
|
getChild<LLUICtrl>("shinyOffsetU")->setValue(offset_x);
|
|
getChild<LLUICtrl>("shinyOffsetV")->setValue(offset_y);
|
|
getChild<LLColorSwatchCtrl>("shinycolorswatch")->setOriginal(material->getSpecularLightColor());
|
|
getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE);
|
|
getChild<LLUICtrl>("glossiness")->setValue((F32)(material->getSpecularLightExponent())/255.0);
|
|
getChild<LLUICtrl>("environment")->setValue((F32)(material->getEnvironmentIntensity())/255.0);
|
|
}
|
|
|
|
// Bumpy (normal)
|
|
texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
|
|
texture_ctrl->setImageAssetID(material->getNormalID());
|
|
if (!material->getNormalID().isNull())
|
|
{
|
|
material->getNormalOffset(offset_x,offset_y);
|
|
material->getNormalRepeat(repeat_x,repeat_y);
|
|
rot = material->getNormalRotation();
|
|
LLCtrlSelectionInterface* combobox_bumpiness =
|
|
childGetSelectionInterface("combobox bumpiness");
|
|
if (combobox_bumpiness)
|
|
{
|
|
combobox_bumpiness->selectNthItem(BUMPY_TEXTURE);
|
|
}
|
|
else
|
|
{
|
|
llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
|
|
}
|
|
getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x);
|
|
getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y);
|
|
getChild<LLUICtrl>("bumpyRot")->setValue(rot);
|
|
getChild<LLUICtrl>("bumpyOffsetU")->setValue(offset_x);
|
|
getChild<LLUICtrl>("bumpyOffsetV")->setValue(offset_y);
|
|
}
|
|
}
|
|
|
|
void LLPanelFace::updateMaterial()
|
|
{
|
|
if (mUpdateInFlight)
|
|
{
|
|
LL_WARNS("Materials") << "Attempt to update material while a previous update is pending ignored." << LL_ENDL;
|
|
return;
|
|
}
|
|
LLComboBox* comboAlphaMode = getChild<LLComboBox>("combobox alphamode");
|
|
LLComboBox* comboBumpiness = getChild<LLComboBox>("combobox bumpiness");
|
|
LLComboBox* comboShininess = getChild<LLComboBox>("combobox shininess");
|
|
if (!comboAlphaMode || !comboBumpiness || !comboShininess)
|
|
{
|
|
return;
|
|
}
|
|
U32 alpha_mode = comboAlphaMode->getCurrentIndex();
|
|
U32 bumpiness = comboBumpiness->getCurrentIndex();
|
|
U32 shininess = comboShininess->getCurrentIndex();
|
|
if ((mIsAlpha && (alpha_mode != ALPHAMODE_BLEND))
|
|
|| (bumpiness == BUMPY_TEXTURE)
|
|
|| (shininess == SHINY_TEXTURE))
|
|
{
|
|
// The user's specified something that needs a material.
|
|
if (!mMaterial)
|
|
{
|
|
mMaterial = LLMaterialPtr(new LLMaterial());
|
|
}
|
|
if (bumpiness == BUMPY_TEXTURE)
|
|
{
|
|
mMaterial->setNormalID(getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID());
|
|
mMaterial->setNormalOffset(getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal(),
|
|
getChild<LLUICtrl>("bumpyOffsetV")->getValue().asReal());
|
|
mMaterial->setNormalRepeat(getChild<LLUICtrl>("bumpyScaleU")->getValue().asReal(),
|
|
getChild<LLUICtrl>("bumpyScaleV")->getValue().asReal());
|
|
mMaterial->setNormalRotation(getChild<LLUICtrl>("bumpyRot")->getValue().asReal());
|
|
}
|
|
else
|
|
{
|
|
mMaterial->setNormalID(LLUUID());
|
|
mMaterial->setNormalOffset(0.0f,0.0f);
|
|
mMaterial->setNormalRepeat(1.0f,1.0f);
|
|
mMaterial->setNormalRotation(0.0f);
|
|
}
|
|
if (shininess == SHINY_TEXTURE)
|
|
{
|
|
mMaterial->setSpecularID(getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID());
|
|
mMaterial->setSpecularOffset(getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal(),
|
|
getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal());
|
|
mMaterial->setSpecularRepeat(getChild<LLUICtrl>("shinyScaleU")->getValue().asReal(),
|
|
getChild<LLUICtrl>("shinyScaleV")->getValue().asReal());
|
|
mMaterial->setSpecularRotation(getChild<LLUICtrl>("shinyRot")->getValue().asReal());
|
|
}
|
|
else
|
|
{
|
|
mMaterial->setSpecularID(LLUUID());
|
|
mMaterial->setSpecularOffset(0.0f,0.0f);
|
|
mMaterial->setSpecularRepeat(1.0f,1.0f);
|
|
mMaterial->setSpecularRotation(0.0f);
|
|
}
|
|
mMaterial->setSpecularLightColor(getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
|
|
mMaterial->setSpecularLightExponent((U8)(255*getChild<LLUICtrl>("glossiness")->getValue().asReal()));
|
|
mMaterial->setEnvironmentIntensity((U8)(255*getChild<LLUICtrl>("environment")->getValue().asReal()));
|
|
mMaterial->setDiffuseAlphaMode(getChild<LLComboBox>("combobox alphamode")->getCurrentIndex());
|
|
mMaterial->setAlphaMaskCutoff((U8)(getChild<LLUICtrl>("maskcutoff")->getValue().asInteger()));
|
|
llinfos << "Updating material: " << mMaterial->asLLSD() << llendl;
|
|
LLSelectMgr::getInstance()->selectionSetMaterial( mMaterial );
|
|
|
|
// We've sent an update. Need to hold off on any more until
|
|
// the sim acknowledges this one.
|
|
mUpdateInFlight = true;
|
|
}
|
|
else
|
|
{
|
|
// The user has specified settings that don't need a material.
|
|
if (mMaterial || !mMaterialID.isNull())
|
|
{
|
|
llinfos << "Resetting material entry" << llendl;
|
|
mMaterial.reset();
|
|
mMaterialID = LLMaterialID::null;
|
|
// Delete existing material entry...
|
|
|
|
// Hold off any further updates till this one's
|
|
// acknowledged.
|
|
//mUpdateInFlight = true;
|
|
}
|
|
}
|
|
|
|
// We've taken care of the update, so clear the update pending flag.
|
|
mUpdatePending = false;
|
|
}
|
|
|
|
//
|
|
// Static functions
|
|
//
|
|
|
|
// static
|
|
F32 LLPanelFace::valueGlow(LLViewerObject* object, S32 face)
|
|
{
|
|
return (F32)(object->getTE(face)->getGlow());
|
|
}
|
|
|
|
|
|
void LLPanelFace::onCommitColor(const LLSD& data)
|
|
{
|
|
sendColor();
|
|
}
|
|
|
|
void LLPanelFace::onCommitShinyColor(const LLSD& data)
|
|
{
|
|
if (!mUpdateInFlight)
|
|
{
|
|
updateMaterial();
|
|
}
|
|
else
|
|
{
|
|
mUpdatePending = true;
|
|
}
|
|
}
|
|
|
|
void LLPanelFace::onCommitAlpha(const LLSD& data)
|
|
{
|
|
sendAlpha();
|
|
}
|
|
|
|
void LLPanelFace::onCancelColor(const LLSD& data)
|
|
{
|
|
LLSelectMgr::getInstance()->selectionRevertColors();
|
|
}
|
|
|
|
void LLPanelFace::onSelectColor(const LLSD& data)
|
|
{
|
|
LLSelectMgr::getInstance()->saveSelectedObjectColors();
|
|
sendColor();
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia");
|
|
LLComboBox* combo_mattype = self->getChild<LLComboBox>("combobox mattype");
|
|
LLComboBox* combo_shininess = self->getChild<LLComboBox>("combobox shininess");
|
|
LLComboBox* combo_bumpiness = self->getChild<LLComboBox>("combobox bumpiness");
|
|
if (!combo_mattype || !combo_matmedia || !combo_shininess || !combo_bumpiness)
|
|
{
|
|
llwarns << "Combo box not found...exiting." << llendl;
|
|
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();
|
|
self->getChildView("combobox mattype")->setVisible(!show_media);
|
|
self->getChildView("rptctrl")->setVisible(!show_media);
|
|
|
|
// Media controls
|
|
self->getChildView("media_info")->setVisible(show_media);
|
|
self->getChildView("add_media")->setVisible(show_media);
|
|
self->getChildView("delete_media")->setVisible(show_media);
|
|
self->getChildView("button align")->setVisible(show_media);
|
|
|
|
// Diffuse texture controls
|
|
self->getChildView("texture control")->setVisible(show_texture);
|
|
self->getChildView("label alphamode")->setVisible(show_texture);
|
|
self->getChildView("combobox alphamode")->setVisible(show_texture);
|
|
self->getChildView("label maskcutoff")->setVisible(false);
|
|
self->getChildView("maskcutoff")->setVisible(false);
|
|
if (show_texture)
|
|
{
|
|
updateAlphaControls(ctrl, userdata);
|
|
}
|
|
self->getChildView("TexScaleU")->setVisible(show_texture);
|
|
self->getChildView("TexScaleV")->setVisible(show_texture);
|
|
self->getChildView("TexRot")->setVisible(show_texture);
|
|
self->getChildView("TexOffsetU")->setVisible(show_texture);
|
|
self->getChildView("TexOffsetV")->setVisible(show_texture);
|
|
|
|
// Specular map controls
|
|
self->getChildView("shinytexture control")->setVisible(show_shininess);
|
|
self->getChildView("combobox shininess")->setVisible(show_shininess);
|
|
self->getChildView("label shininess")->setVisible(show_shininess);
|
|
self->getChildView("label glossiness")->setVisible(false);
|
|
self->getChildView("glossiness")->setVisible(false);
|
|
self->getChildView("label environment")->setVisible(false);
|
|
self->getChildView("environment")->setVisible(false);
|
|
self->getChildView("label shinycolor")->setVisible(false);
|
|
self->getChildView("shinycolorswatch")->setVisible(false);
|
|
if (show_shininess)
|
|
{
|
|
updateShinyControls(ctrl, userdata);
|
|
}
|
|
self->getChildView("shinyScaleU")->setVisible(show_shininess);
|
|
self->getChildView("shinyScaleV")->setVisible(show_shininess);
|
|
self->getChildView("shinyRot")->setVisible(show_shininess);
|
|
self->getChildView("shinyOffsetU")->setVisible(show_shininess);
|
|
self->getChildView("shinyOffsetV")->setVisible(show_shininess);
|
|
|
|
// Normal map controls
|
|
self->getChildView("bumpytexture control")->setVisible(show_bumpiness);
|
|
self->getChildView("combobox bumpiness")->setVisible(show_bumpiness);
|
|
self->getChildView("label bumpiness")->setVisible(show_bumpiness);
|
|
self->getChildView("bumpyScaleU")->setVisible(show_bumpiness);
|
|
self->getChildView("bumpyScaleV")->setVisible(show_bumpiness);
|
|
self->getChildView("bumpyRot")->setVisible(show_bumpiness);
|
|
self->getChildView("bumpyOffsetU")->setVisible(show_bumpiness);
|
|
self->getChildView("bumpyOffsetV")->setVisible(show_bumpiness);
|
|
|
|
// Enable texture scale/rotation/offset parameters if there's one
|
|
// present to set for
|
|
bool texParmsEnable = show_texture ||
|
|
(show_shininess && (combo_shininess->getCurrentIndex() == SHINY_TEXTURE)) ||
|
|
(show_bumpiness && (combo_bumpiness->getCurrentIndex() == BUMPY_TEXTURE));
|
|
self->getChildView("tex gen")->setEnabled(texParmsEnable);
|
|
self->getChildView("combobox texgen")->setEnabled(texParmsEnable);
|
|
self->getChildView("rptctrl")->setEnabled(texParmsEnable);
|
|
self->getChildView("TexScaleU")->setEnabled(texParmsEnable);
|
|
self->getChildView("TexScaleV")->setEnabled(texParmsEnable);
|
|
self->getChildView("TexRot")->setEnabled(texParmsEnable);
|
|
self->getChildView("TexOffsetU")->setEnabled(texParmsEnable);
|
|
self->getChildView("TexOffsetV")->setEnabled(texParmsEnable);
|
|
self->getChildView("shinyScaleU")->setEnabled(texParmsEnable);
|
|
self->getChildView("shinyScaleV")->setEnabled(texParmsEnable);
|
|
self->getChildView("shinyRot")->setEnabled(texParmsEnable);
|
|
self->getChildView("shinyOffsetU")->setEnabled(texParmsEnable);
|
|
self->getChildView("shinyOffsetV")->setEnabled(texParmsEnable);
|
|
self->getChildView("bumpyScaleU")->setEnabled(texParmsEnable);
|
|
self->getChildView("bumpyScaleV")->setEnabled(texParmsEnable);
|
|
self->getChildView("bumpyRot")->setEnabled(texParmsEnable);
|
|
self->getChildView("bumpyOffsetU")->setEnabled(texParmsEnable);
|
|
self->getChildView("bumpyOffsetV")->setEnabled(texParmsEnable);
|
|
self->getChildView("checkbox planar align")->setEnabled(texParmsEnable);
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
onCommitMaterialsMedia(ctrl, userdata);
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
self->sendBump();
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
self->sendTexGen();
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::updateShinyControls(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
LLComboBox* comboShiny = self->getChild<LLComboBox>("combobox shininess");
|
|
if (!comboShiny)
|
|
{
|
|
return;
|
|
}
|
|
U32 shiny_value = comboShiny->getCurrentIndex();
|
|
bool show_shinyctrls = (shiny_value == SHINY_TEXTURE); // Use texture
|
|
self->getChildView("label glossiness")->setVisible(show_shinyctrls);
|
|
self->getChildView("glossiness")->setVisible(show_shinyctrls);
|
|
self->getChildView("label environment")->setVisible(show_shinyctrls);
|
|
self->getChildView("environment")->setVisible(show_shinyctrls);
|
|
self->getChildView("label shinycolor")->setVisible(show_shinyctrls);
|
|
self->getChildView("shinycolorswatch")->setVisible(show_shinyctrls);
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
self->sendShiny();
|
|
if (!self->mUpdateInFlight)
|
|
{
|
|
self->updateMaterial();
|
|
}
|
|
else
|
|
{
|
|
self->mUpdatePending = true;
|
|
}
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::updateAlphaControls(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
LLComboBox* comboAlphaMode = self->getChild<LLComboBox>("combobox alphamode");
|
|
if (!comboAlphaMode)
|
|
{
|
|
return;
|
|
}
|
|
U32 alpha_value = comboAlphaMode->getCurrentIndex();
|
|
bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
|
|
self->getChildView("label maskcutoff")->setVisible(show_alphactrls);
|
|
self->getChildView("maskcutoff")->setVisible(show_alphactrls);
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
updateAlphaControls(ctrl,userdata);
|
|
if (!self->mUpdateInFlight)
|
|
{
|
|
self->updateMaterial();
|
|
}
|
|
else
|
|
{
|
|
self->mUpdatePending = true;
|
|
}
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitFullbright(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
self->sendFullbright();
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
self->sendGlow();
|
|
}
|
|
|
|
// 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();
|
|
}
|
|
|
|
void LLPanelFace::onCommitMaterialTexture( const LLSD& data )
|
|
{
|
|
if (!mUpdateInFlight)
|
|
{
|
|
updateMaterial();
|
|
}
|
|
else
|
|
{
|
|
mUpdatePending = true;
|
|
}
|
|
}
|
|
|
|
void LLPanelFace::onCancelMaterialTexture(const LLSD& data)
|
|
{
|
|
// not sure what to do here other than
|
|
if (!mUpdateInFlight)
|
|
{
|
|
updateMaterial();
|
|
}
|
|
else
|
|
{
|
|
mUpdatePending = true;
|
|
}
|
|
}
|
|
|
|
void LLPanelFace::onSelectMaterialTexture(const LLSD& data)
|
|
{
|
|
if (!mUpdateInFlight)
|
|
{
|
|
updateMaterial();
|
|
}
|
|
else
|
|
{
|
|
mUpdatePending = true;
|
|
}
|
|
}
|
|
|
|
//static
|
|
void LLPanelFace::onCommitMaterial(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
if (!self->mUpdateInFlight)
|
|
{
|
|
self->updateMaterial();
|
|
}
|
|
else
|
|
{
|
|
self->mUpdatePending = true;
|
|
}
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
self->sendTextureInfo();
|
|
}
|
|
|
|
// Commit the number of repeats per meter
|
|
// static
|
|
void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
|
|
gFocusMgr.setKeyboardFocus( NULL );
|
|
|
|
//F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get();
|
|
F32 repeats_per_meter = (F32)self->getChild<LLUICtrl>("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get();
|
|
LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
|
|
}
|
|
|
|
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(void* userdata)
|
|
{
|
|
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)
|
|
{
|
|
}
|
|
|
|
// static
|
|
void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
|
|
{
|
|
LLPanelFace* self = (LLPanelFace*) userdata;
|
|
self->getState();
|
|
self->sendTextureInfo();
|
|
}
|
|
|
|
void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
|
|
{
|
|
LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype");
|
|
if (!combo_mattype)
|
|
{
|
|
return;
|
|
}
|
|
U32 mattype = combo_mattype->getCurrentIndex();
|
|
std::string which_control="texture control";
|
|
switch (mattype)
|
|
{
|
|
case MATTYPE_SPECULAR:
|
|
which_control = "shinytexture control";
|
|
break;
|
|
case MATTYPE_NORMAL:
|
|
which_control = "bumpytexture control";
|
|
break;
|
|
// no default needed
|
|
}
|
|
|
|
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(which_control);
|
|
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("TextureLivePreview"))
|
|
{
|
|
LLNotificationsUtil::add("LivePreviewUnavailable");
|
|
}
|
|
}
|
|
}
|