llpanelface.cpp 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393
  1. /**
  2. * @file llpanelface.cpp
  3. * @brief Panel in the tools floater for editing face textures, colors, etc.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, Linden Research, Inc, (c) 2009-2024 Henri Beauchamp
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llpanelface.h"
  34. #include "llavatarappearancedefines.h"
  35. #include "llbutton.h"
  36. #include "llcheckboxctrl.h"
  37. #include "llcombobox.h"
  38. #include "lllineeditor.h"
  39. #include "llpluginclassmedia.h"
  40. #include "llradiogroup.h"
  41. #include "llspinctrl.h"
  42. #include "llrenderutils.h"
  43. #include "lltextbox.h"
  44. #include "lluictrlfactory.h"
  45. #include "llagent.h"
  46. #include "llcolorswatch.h"
  47. #include "lldrawpoolbump.h"
  48. #include "llface.h"
  49. #include "hbfloaterinvitemspicker.h"
  50. #include "llfloatertools.h"
  51. #include "llgltfmateriallist.h"
  52. #include "llgltfmaterialpreview.h"
  53. #include "lllocalgltfmaterials.h"
  54. #include "llmaterialmgr.h"
  55. #include "llpipeline.h" // For LLPipeline::sReflectionProbesEnabled
  56. #include "llpreviewmaterial.h"
  57. #include "llselectmgr.h"
  58. #include "lltexturectrl.h"
  59. #include "lltextureentry.h"
  60. #include "lltooldraganddrop.h"
  61. #include "llviewercontrol.h"
  62. #include "llviewermedia.h"
  63. #include "llviewerobject.h"
  64. #include "llviewerregion.h"
  65. #include "llviewerstats.h"
  66. #include "llviewertexturelist.h"
  67. using namespace LLAvatarAppearanceDefines;
  68. // Constant definitions for comboboxes
  69. // Must match the UI elements definitions in floater_tools.xml
  70. constexpr S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture
  71. constexpr S32 MATTYPE_NORMAL = 1; // Normal map
  72. constexpr S32 MATTYPE_SPECULAR = 2; // Specular map
  73. constexpr S32 MATTYPE_PBR = 3; // PBR GLTF material
  74. constexpr S32 BUMPY_TEXTURE = 18; // use supplied normal map
  75. constexpr S32 SHINY_TEXTURE = 4; // use supplied specular map
  76. constexpr S32 ALPHAMODE_NONE = 0; // No alpha mask applied
  77. constexpr S32 ALPHAMODE_BLEND = 1; // Alpha blending mode
  78. constexpr S32 ALPHAMODE_MASK = 2; // Alpha masking mode
  79. constexpr S32 ALPHAMODE_EMISSIVE = 3; // Emissive masking mode
  80. //static
  81. LLPanelFace* LLPanelFace::sInstance = NULL;
  82. //
  83. // Methods
  84. //
  85. LLPanelFace::LLPanelFace(const std::string& name)
  86. : LLPanel(name),
  87. mHasMultiplePbrSelection(false),
  88. mIsAlpha(false)
  89. {
  90. sInstance = this;
  91. }
  92. LLPanelFace::~LLPanelFace()
  93. {
  94. // Children all cleaned up by default view destructor.
  95. sInstance = NULL;
  96. }
  97. //virtual
  98. bool LLPanelFace::postBuild()
  99. {
  100. setMouseOpaque(false);
  101. // Face color label and swatch
  102. mLabelDiffuseColor = getChild<LLTextBox>("color_text");
  103. mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
  104. mColorSwatch->setCommitCallback(onCommitColor);
  105. mColorSwatch->setOnCancelCallback(onCancelColor);
  106. mColorSwatch->setOnSelectCallback(onSelectColor);
  107. mColorSwatch->setCallbackUserData(this);
  108. mColorSwatch->setCanApplyImmediately(false);
  109. // Face transparency
  110. mLabelColorTransp = getChild<LLTextBox>("color trans");
  111. mTransparency = getChild<LLSpinCtrl>("ColorTrans");
  112. mTransparency->setCommitCallback(onCommitAlpha);
  113. mTransparency->setCallbackUserData(this);
  114. mTransparency->setPrecision(0);
  115. // Face glow strength
  116. mGlow = getChild<LLSpinCtrl>("glow");
  117. mGlow->setCommitCallback(onCommitGlow);
  118. mGlow->setCallbackUserData(this);
  119. // Face full bright
  120. mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
  121. mCheckFullbright->setCommitCallback(onCommitFullbright);
  122. mCheckFullbright->setCallbackUserData(this);
  123. mButtonResetMaterial = getChild<LLButton>("reset_material");
  124. mButtonResetMaterial->setClickedCallback(onClickRemoveMaterial, this);
  125. #if 0
  126. mButtonAlignMap = getChild<LLButton>("btn_align_map");
  127. mButtonAlignMap->setClickedCallback(onAlignTextureLayers, this);
  128. #else
  129. childHide("btn_align_map");
  130. #endif
  131. mLabelMaps = getChild<LLTextBox>("label maps");
  132. mMapsRadio = getChild<LLRadioGroup>("map_selector");
  133. mMapsRadio->setCommitCallback(onSelectMapType);
  134. mMapsRadio->setCallbackUserData(this);
  135. // PBR material buttons
  136. mButtonEditPBR = getChild<LLButton>("btn_edit_pbr");
  137. mButtonEditPBR->setClickedCallback(onClickEditPBR, this);
  138. mButtonLocalPBR = getChild<LLButton>("btn_local_pbr");
  139. mButtonLocalPBR->setClickedCallback(onClickLocalPBR, this);
  140. mButtonLoadPBR = getChild<LLButton>("btn_load_pbr");
  141. mButtonLoadPBR->setClickedCallback(onClickLoadPBR, this);
  142. mButtonSavePBR = getChild<LLButton>("btn_save_pbr");
  143. mButtonSavePBR->setClickedCallback(onClickSavePBR, this);
  144. // PBR material preview
  145. mPbrThumbBorder = getChild<LLView>("pbr_mat_border");
  146. mThumbnailRect = mPbrThumbBorder->getRect();
  147. // Adjust to keep the view border showing while we will draw the thumbnail
  148. // inside it.
  149. ++mThumbnailRect.mBottom;
  150. --mThumbnailRect.mTop;
  151. ++mThumbnailRect.mLeft;
  152. --mThumbnailRect.mRight;
  153. mLabelPbrPreview = getChild<LLTextBox>("pbr_mat_text");
  154. std::string tex_id = gSavedSettings.getString("DefaultObjectTexture");
  155. mTextureCtrl = getChild<LLTextureCtrl>("texture control");
  156. mTextureCtrl->setDefaultImageAssetID(LLUUID(tex_id));
  157. mTextureCtrl->setCommitCallback(onCommitTexture);
  158. mTextureCtrl->setOnCancelCallback(onCancelTexture);
  159. mTextureCtrl->setOnSelectCallback(onSelectTexture);
  160. mTextureCtrl->setDragCallback(onDragTexture);
  161. mTextureCtrl->setCallbackUserData(this);
  162. mTextureCtrl->setCanApplyImmediately(false);
  163. // Diffuse map parameters
  164. mLabelAlphaMode = getChild<LLTextBox>("label alphamode");
  165. mComboAlphaMode = getChild<LLComboBox>("combobox alphamode");
  166. mComboAlphaMode->setCommitCallback(onCommitAlphaMode);
  167. mComboAlphaMode->setCallbackUserData(this);
  168. mLabelMaskCutoff = getChild<LLTextBox>("label maskcutoff");
  169. mMaskCutoff = getChild<LLSpinCtrl>("maskcutoff");
  170. mMaskCutoff->setCommitCallback(onCommitAlphaMaterial);
  171. mMaskCutoff->setCallbackUserData(this);
  172. // Normal map texture picker
  173. mNormalCtrl = getChild<LLTextureCtrl>("normal control");
  174. tex_id = gSavedSettings.getString("DefaultNormalTexture");
  175. mNormalCtrl->setDefaultImageAssetID(LLUUID(tex_id));
  176. tex_id = gSavedSettings.getString("BlankNormalTexture");
  177. mNormalCtrl->setBlankImageAssetID(LLUUID(tex_id));
  178. mNormalCtrl->setCommitCallback(onCommitNormalMap);
  179. mNormalCtrl->setOnSelectCallback(onCommitNormalMap);
  180. mNormalCtrl->setOnCancelCallback(NULL);
  181. mNormalCtrl->setDragCallback(onDragTexture);
  182. mNormalCtrl->setCallbackUserData(this);
  183. mNormalCtrl->setCanApplyImmediately(false);
  184. // Specular map texture picker and parameters
  185. mSpecularCtrl = getChild<LLTextureCtrl>("specular control");
  186. mSpecularCtrl->setDefaultImageAssetID(LLUUID::null);
  187. mSpecularCtrl->setCommitCallback(onCommitSpecularMap);
  188. mSpecularCtrl->setOnSelectCallback(onCommitSpecularMap);
  189. mSpecularCtrl->setOnCancelCallback(NULL);
  190. mSpecularCtrl->setDragCallback(onDragTexture);
  191. mSpecularCtrl->setCallbackUserData(this);
  192. mSpecularCtrl->setCanApplyImmediately(false);
  193. mLabelShinyColor = getChild<LLTextBox>("label shinycolor");
  194. mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
  195. mShinyColorSwatch->setCommitCallback(onCommitShinyColor);
  196. mShinyColorSwatch->setOnSelectCallback(onCommitShinyColor);
  197. mShinyColorSwatch->setOnCancelCallback(NULL);
  198. mShinyColorSwatch->setCallbackUserData(this);
  199. mShinyColorSwatch->setCanApplyImmediately(false);
  200. mLabelGlossiness = getChild<LLTextBox>("label glossiness");
  201. mGlossiness = getChild<LLSpinCtrl>("glossiness");
  202. mGlossiness->setCommitCallback(onCommitShinyMaterial);
  203. mGlossiness->setCallbackUserData(this);
  204. mLabelEnvironment = getChild<LLTextBox>("label environment");
  205. mEnvironment = getChild<LLSpinCtrl>("environment");
  206. mEnvironment->setCommitCallback(onCommitShinyMaterial);
  207. mEnvironment->setCallbackUserData(this);
  208. // Use texture element text for normal and specular combo boxes
  209. mUseTextureText = getString("use_texture");
  210. mLabelShininess = getChild<LLTextBox>("label shininess");
  211. mComboShininess = getChild<LLComboBox>("combobox shininess");
  212. mComboShininess->setCommitCallback(onCommitShiny);
  213. mComboShininess->setCallbackUserData(this);
  214. mLabelBumpiness = getChild<LLTextBox>("label bumpiness");
  215. mComboBumpiness = getChild<LLComboBox>("combobox bumpiness");
  216. mComboBumpiness->setCommitCallback(onCommitBump);
  217. mComboBumpiness->setCallbackUserData(this);
  218. // Default and Planar alignment
  219. mLabelTexGen = getChild<LLTextBox>("tex gen");
  220. mComboTexGen = getChild<LLComboBox>("combobox texgen");
  221. mComboTexGen->setCommitCallback(onCommitTexGen);
  222. mComboTexGen->setCallbackUserData(this);
  223. mCheckPlanarAlign = getChild<LLCheckBoxCtrl>("checkbox planar align");
  224. mCheckPlanarAlign->setCommitCallback(onCommitPlanarAlign);
  225. mCheckPlanarAlign->setCallbackUserData(this);
  226. // Repeats per face/meter, offset and rotation labels
  227. mLabelRepeats = getChild<LLTextBox>("rpt");
  228. mLabelTexScale = getChild<LLTextBox>("tex scale");
  229. mLabelTexScaleUnit = getChild<LLTextBox>("tex scale unit");
  230. mLabelTexScaleHoriz = getChild<LLTextBox>("tex scale horiz");
  231. mLabelTexScaleVert = getChild<LLTextBox>("tex scale vert");
  232. mLabelTexOffset = getChild<LLTextBox>("tex offset");
  233. mLabelTexOffsetHoriz = getChild<LLTextBox>("tex offset horiz");
  234. mLabelTexOffsetVert = getChild<LLTextBox>("tex offset vert");
  235. mLabelTexRotate = getChild<LLTextBox>("tex rotate");
  236. mRepeatsPerMeterText = getString("string repeats per meter");
  237. mRepeatsPerFaceText = getString("string repeats per face");
  238. // Repeats per meter spinner (used for all maps)
  239. mRepeats = getChild<LLSpinCtrl>("rptctrl");
  240. mRepeats->setCommitCallback(onCommitRepeatsPerMeter);
  241. mRepeats->setCallbackUserData(this);
  242. // Texture scale, offset and rotation
  243. mTexScaleU = getChild<LLSpinCtrl>("TexScaleU");
  244. mTexScaleU->setCommitCallback(onCommitTextureInfo);
  245. mTexScaleU->setCallbackUserData(this);
  246. mCheckTexFlipS = getChild<LLCheckBoxCtrl>("TexFlipS");
  247. mCheckTexFlipS->setCommitCallback(onCommitTextureInfo);
  248. mCheckTexFlipS->setCallbackUserData(this);
  249. mTexScaleV = getChild<LLSpinCtrl>("TexScaleV");
  250. mTexScaleV->setCommitCallback(onCommitTextureInfo);
  251. mTexScaleV->setCallbackUserData(this);
  252. mCheckTexFlipT = getChild<LLCheckBoxCtrl>("TexFlipT");
  253. mCheckTexFlipT->setCommitCallback(onCommitTextureInfo);
  254. mCheckTexFlipT->setCallbackUserData(this);
  255. mTexOffsetU = getChild<LLSpinCtrl>("TexOffsetU");
  256. mTexOffsetU->setCommitCallback(onCommitTextureInfo);
  257. mTexOffsetU->setCallbackUserData(this);
  258. mTexOffsetV = getChild<LLSpinCtrl>("TexOffsetV");
  259. mTexOffsetV->setCommitCallback(onCommitTextureInfo);
  260. mTexOffsetV->setCallbackUserData(this);
  261. mTexRot = getChild<LLSpinCtrl>("TexRot");
  262. mTexRot->setCommitCallback(onCommitTextureInfo);
  263. mTexRot->setCallbackUserData(this);
  264. // Normal map scale, offset and rotation
  265. mBumpyScaleU = getChild<LLSpinCtrl>("BumpyScaleU");
  266. mBumpyScaleU->setCommitCallback(onCommitBumpyMaterial);
  267. mBumpyScaleU->setCallbackUserData(this);
  268. mCheckBumpyFlipS = getChild<LLCheckBoxCtrl>("BumpyFlipS");
  269. mCheckBumpyFlipS->setCommitCallback(onCommitBumpyMaterial);
  270. mCheckBumpyFlipS->setCallbackUserData(this);
  271. mBumpyScaleV = getChild<LLSpinCtrl>("BumpyScaleV");
  272. mBumpyScaleV->setCommitCallback(onCommitBumpyMaterial);
  273. mBumpyScaleV->setCallbackUserData(this);
  274. mCheckBumpyFlipT = getChild<LLCheckBoxCtrl>("BumpyFlipT");
  275. mCheckBumpyFlipT->setCommitCallback(onCommitBumpyMaterial);
  276. mCheckBumpyFlipT->setCallbackUserData(this);
  277. mBumpyOffsetU = getChild<LLSpinCtrl>("BumpyOffsetU");
  278. mBumpyOffsetU->setCommitCallback(onCommitBumpyMaterial);
  279. mBumpyOffsetU->setCallbackUserData(this);
  280. mBumpyOffsetV = getChild<LLSpinCtrl>("BumpyOffsetV");
  281. mBumpyOffsetV->setCommitCallback(onCommitBumpyMaterial);
  282. mBumpyOffsetV->setCallbackUserData(this);
  283. mBumpyRot = getChild<LLSpinCtrl>("BumpyRot");
  284. mBumpyRot->setCommitCallback(onCommitBumpyMaterial);
  285. mBumpyRot->setCallbackUserData(this);
  286. // Specular map scale, offset and rotation
  287. mShinyScaleU = getChild<LLSpinCtrl>("ShinyScaleU");
  288. mShinyScaleU->setCommitCallback(onCommitShinyMaterial);
  289. mShinyScaleU->setCallbackUserData(this);
  290. mCheckShinyFlipS = getChild<LLCheckBoxCtrl>("ShinyFlipS");
  291. mCheckShinyFlipS->setCommitCallback(onCommitShinyMaterial);
  292. mCheckShinyFlipS->setCallbackUserData(this);
  293. mShinyScaleV = getChild<LLSpinCtrl>("ShinyScaleV");
  294. mShinyScaleV->setCommitCallback(onCommitShinyMaterial);
  295. mShinyScaleV->setCallbackUserData(this);
  296. mCheckShinyFlipT = getChild<LLCheckBoxCtrl>("ShinyFlipT");
  297. mCheckShinyFlipT->setCommitCallback(onCommitShinyMaterial);
  298. mCheckShinyFlipT->setCallbackUserData(this);
  299. mShinyOffsetU = getChild<LLSpinCtrl>("ShinyOffsetU");
  300. mShinyOffsetU->setCommitCallback(onCommitShinyMaterial);
  301. mShinyOffsetU->setCallbackUserData(this);
  302. mShinyOffsetV = getChild<LLSpinCtrl>("ShinyOffsetV");
  303. mShinyOffsetV->setCommitCallback(onCommitShinyMaterial);
  304. mShinyOffsetV->setCallbackUserData(this);
  305. mShinyRot = getChild<LLSpinCtrl>("ShinyRot");
  306. mShinyRot->setCommitCallback(onCommitShinyMaterial);
  307. mShinyRot->setCallbackUserData(this);
  308. // PBR material scale, offset and rotation
  309. mPbrScaleU = getChild<LLSpinCtrl>("PbrScaleU");
  310. mPbrScaleU->setCommitCallback(onCommitPbrMaterial);
  311. mPbrScaleU->setCallbackUserData(this);
  312. mPbrScaleV = getChild<LLSpinCtrl>("PbrScaleV");
  313. mPbrScaleV->setCommitCallback(onCommitPbrMaterial);
  314. mPbrScaleV->setCallbackUserData(this);
  315. mPbrOffsetU = getChild<LLSpinCtrl>("PbrOffsetU");
  316. mPbrOffsetU->setCommitCallback(onCommitPbrMaterial);
  317. mPbrOffsetU->setCallbackUserData(this);
  318. mPbrOffsetV = getChild<LLSpinCtrl>("PbrOffsetV");
  319. mPbrOffsetV->setCommitCallback(onCommitPbrMaterial);
  320. mPbrOffsetV->setCallbackUserData(this);
  321. mPbrRot = getChild<LLSpinCtrl>("PbrRot");
  322. mPbrRot->setCommitCallback(onCommitPbrMaterial);
  323. mPbrRot->setCallbackUserData(this);
  324. // Media stuff
  325. // *TODO: move the face-related media stuff from llfloatertools.cpp to here
  326. mLabelMedia = getChild<LLTextBox>("media label");
  327. mButtonAlignMedia = getChild<LLButton>("button align");
  328. mButtonAlignMedia->setClickedCallback(onClickAutoFix, this);
  329. clearCtrls();
  330. return true;
  331. }
  332. struct LLPanelFaceSetTEFunctor final : public LLSelectedTEFunctor
  333. {
  334. LLPanelFaceSetTEFunctor(LLPanelFace* panelp)
  335. : mPanel(panelp)
  336. {
  337. }
  338. bool apply(LLViewerObject* objectp, S32 te) override;
  339. private:
  340. LLPanelFace* mPanel;
  341. };
  342. // Functor that aligns a face to mCenterFace
  343. struct LLPanelFaceSetAlignedTEFunctor final : public LLSelectedTEFunctor
  344. {
  345. LLPanelFaceSetAlignedTEFunctor(LLPanelFace* panelp, LLFace* center_facep,
  346. S32 map = -1)
  347. : mPanel(panelp),
  348. mCenterFace(center_facep),
  349. mMap(map)
  350. {
  351. }
  352. template<void (LLMaterial::*MaterialEditFunc)(F32 data)>
  353. struct LLMaterialEditFunctor
  354. {
  355. LLMaterialEditFunctor(const F32& data)
  356. : mData(data)
  357. {
  358. }
  359. void apply(LLMaterialPtr& matp)
  360. {
  361. (matp->*(MaterialEditFunc))(mData);
  362. }
  363. F32 mData;
  364. };
  365. // Updates material parameters by applying 'MaterialEditFunc' to selected
  366. // TEs
  367. template<void (LLMaterial::*MaterialEditFunc)(F32 data)>
  368. static void edit(LLPanelFace* p, F32 data, S32 te = -1,
  369. const LLUUID& only_for_obj_id = LLUUID::null)
  370. {
  371. LLMaterialEditFunctor<MaterialEditFunc> edit(data);
  372. struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor
  373. {
  374. LLSelectedTEEditMaterial(LLPanelFace* panel,
  375. LLMaterialEditFunctor<MaterialEditFunc>* editp,
  376. const LLUUID& only_for_obj_id)
  377. : mPanelFace(panel),
  378. mEdit(editp),
  379. mOnlyForObjId(only_for_obj_id)
  380. {
  381. }
  382. LLMaterialPtr apply(LLViewerObject* objectp, S32 face,
  383. LLTextureEntry* tep,
  384. LLMaterialPtr& curmatp) override
  385. {
  386. if (!mEdit)
  387. {
  388. return NULL;
  389. }
  390. if (mOnlyForObjId.notNull() &&
  391. mOnlyForObjId != objectp->getID())
  392. {
  393. return NULL;
  394. }
  395. LLMaterialPtr newmatp =
  396. mPanelFace->createDefaultMaterial(curmatp);
  397. if (!newmatp)
  398. {
  399. return NULL;
  400. }
  401. // Determine correct alpha mode for current diffuse texture
  402. // (i.e. does it have an alpha channel that makes alpha mode
  403. // useful)
  404. //
  405. // mPanelFace->isAlpha() "lies" when one face has alpha and
  406. // the rest do not (NORSPEC-329) need to get per-face answer to
  407. // this question for sane alpha mode retention on updates.
  408. bool is_alpha_face = objectp->isImageAlphaBlended(face);
  409. // Need to keep this original answer for valid comparisons in
  410. // logic below
  411. U8 orig_deflt_alpha_mode =
  412. is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND
  413. : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
  414. U8 dflt_alpha_mode =
  415. curmatp.isNull() ? orig_deflt_alpha_mode
  416. : curmatp->getDiffuseAlphaMode();
  417. // Ensure we do not inherit the default of blend by accident;
  418. // this will be stomped by a legit request to change the alpha
  419. // mode by the apply() below.
  420. newmatp->setDiffuseAlphaMode(dflt_alpha_mode);
  421. // Apply change
  422. mEdit->apply(newmatp);
  423. U32 new_alpha_mode = newmatp->getDiffuseAlphaMode();
  424. if (!is_alpha_face &&
  425. new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
  426. {
  427. new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
  428. newmatp->setDiffuseAlphaMode(new_alpha_mode);
  429. }
  430. const LLUUID& obj_id = objectp->getID();
  431. if (new_alpha_mode != orig_deflt_alpha_mode ||
  432. newmatp->getNormalID().notNull() ||
  433. newmatp->getSpecularID().notNull())
  434. {
  435. LL_DEBUGS("Materials") << "Putting material on object "
  436. << obj_id << " - Face " << face
  437. << " - Material: "
  438. << newmatp->asLLSD() << LL_ENDL;
  439. LLMaterialMgr::getInstance()->put(obj_id, face, *newmatp);
  440. }
  441. else
  442. {
  443. LL_DEBUGS("Materials") << "Removing material from object "
  444. << obj_id << " - Face " << face
  445. << LL_ENDL;
  446. LLMaterialMgr::getInstance()->remove(obj_id, face);
  447. newmatp = NULL;
  448. }
  449. objectp->setTEMaterialParams(face, newmatp);
  450. return newmatp;
  451. }
  452. LLMaterialEditFunctor<MaterialEditFunc>* mEdit;
  453. LLPanelFace* mPanelFace;
  454. LLUUID mOnlyForObjId;
  455. } editor(p, &edit, only_for_obj_id);
  456. gSelectMgr.selectionSetMaterialParams(&editor, te);
  457. }
  458. LL_INLINE static void setNormalOffsetX(LLPanelFace* panel, F32 data,
  459. S32 te = -1,
  460. const LLUUID& obj_id = LLUUID::null)
  461. {
  462. edit<&LLMaterial::setNormalOffsetX>(panel, data, te, obj_id);
  463. }
  464. LL_INLINE static void setNormalOffsetY(LLPanelFace* panel, F32 data,
  465. S32 te = -1,
  466. const LLUUID& obj_id = LLUUID::null)
  467. {
  468. edit<&LLMaterial::setNormalOffsetY>(panel, data, te, obj_id);
  469. }
  470. LL_INLINE static void setNormalRepeatX(LLPanelFace* panel, F32 data,
  471. S32 te = -1,
  472. const LLUUID& obj_id = LLUUID::null)
  473. {
  474. edit<&LLMaterial::setNormalRepeatX>(panel, data, te, obj_id);
  475. }
  476. LL_INLINE static void setNormalRepeatY(LLPanelFace* panel, F32 data,
  477. S32 te = -1,
  478. const LLUUID& obj_id = LLUUID::null)
  479. {
  480. edit<&LLMaterial::setNormalRepeatY>(panel, data, te, obj_id);
  481. }
  482. LL_INLINE static void setSpecularOffsetX(LLPanelFace* panel, F32 data,
  483. S32 te = -1,
  484. const LLUUID& obj_id = LLUUID::null)
  485. {
  486. edit<&LLMaterial::setSpecularOffsetX>(panel, data, te, obj_id);
  487. }
  488. LL_INLINE static void setSpecularOffsetY(LLPanelFace* panel, F32 data,
  489. S32 te = -1,
  490. const LLUUID& obj_id = LLUUID::null)
  491. {
  492. edit<&LLMaterial::setSpecularOffsetY>(panel, data, te, obj_id);
  493. }
  494. LL_INLINE static void setSpecularRepeatX(LLPanelFace* panel, F32 data,
  495. S32 te = -1,
  496. const LLUUID& obj_id = LLUUID::null)
  497. {
  498. edit<&LLMaterial::setSpecularRepeatX>(panel, data, te, obj_id);
  499. }
  500. LL_INLINE static void setSpecularRepeatY(LLPanelFace* panel, F32 data,
  501. S32 te = -1,
  502. const LLUUID& obj_id = LLUUID::null)
  503. {
  504. edit<&LLMaterial::setSpecularRepeatY>(panel, data, te, obj_id);
  505. }
  506. LL_INLINE static void setNormalRotation(LLPanelFace* panel, F32 data,
  507. S32 te = -1,
  508. const LLUUID& obj_id = LLUUID::null)
  509. {
  510. edit<&LLMaterial::setNormalRotation>(panel, data, te, obj_id);
  511. }
  512. LL_INLINE static void setSpecularRotation(LLPanelFace* panel, F32 data,
  513. S32 te = -1,
  514. const LLUUID& obj_id = LLUUID::null)
  515. {
  516. edit<&LLMaterial::setSpecularRotation>(panel, data, te, obj_id);
  517. }
  518. bool apply(LLViewerObject* objectp, S32 te) override
  519. {
  520. LLFace* facep = objectp->mDrawable->getFace(te);
  521. if (!facep || !facep->getViewerObject() ||
  522. !facep->getViewerObject()->getVolume() ||
  523. facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
  524. {
  525. // Volume face does not exist, cannot be aligned
  526. return true;
  527. }
  528. bool set_aligned = facep != mCenterFace;
  529. if (set_aligned)
  530. {
  531. LLVector2 uv_offset, uv_scale;
  532. F32 uv_rot;
  533. S32 map = mMap >= 0 ? mMap : LLRender::DIFFUSE_MAP;
  534. set_aligned = facep->calcAlignedPlanarTE(mCenterFace, &uv_offset,
  535. &uv_scale, &uv_rot, map);
  536. if (set_aligned)
  537. {
  538. const LLUUID& obj_id = objectp->getID();
  539. F32 offset_x = uv_offset.mV[VX];
  540. F32 offset_y = uv_offset.mV[VY];
  541. if (mMap == -1 || mMap == LLRender::NORMAL_MAP)
  542. {
  543. setNormalOffsetX(mPanel, offset_x, te, obj_id);
  544. setNormalOffsetY(mPanel, offset_y, te, obj_id);
  545. setNormalRotation(mPanel, uv_rot, te, obj_id);
  546. }
  547. if (mMap == -1 || mMap == LLRender::SPECULAR_MAP)
  548. {
  549. setSpecularOffsetX(mPanel, offset_x, te, obj_id);
  550. setSpecularOffsetY(mPanel, offset_y, te, obj_id);
  551. setSpecularRotation(mPanel, uv_rot, te, obj_id);
  552. }
  553. if (mMap == -1 || mMap == LLRender::DIFFUSE_MAP)
  554. {
  555. objectp->setTEOffset(te, offset_x, offset_y);
  556. objectp->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]);
  557. objectp->setTERotation(te, uv_rot);
  558. }
  559. }
  560. }
  561. if (mMap == -1 && !set_aligned)
  562. {
  563. LLPanelFaceSetTEFunctor setfunc(mPanel);
  564. setfunc.apply(objectp, te);
  565. }
  566. return true;
  567. }
  568. private:
  569. LLPanelFace* mPanel;
  570. LLFace* mCenterFace;
  571. S32 mMap;
  572. };
  573. //virtual
  574. bool LLPanelFaceSetTEFunctor::apply(LLViewerObject* object, S32 te)
  575. {
  576. F32 value;
  577. bool align_planar = mPanel->getPlanarAlign()->get();
  578. LLComboBox* texgen = mPanel->getComboTexGen();
  579. LLSpinCtrl* spinctrl = mPanel->getTexScaleU();
  580. if (align_planar || !spinctrl->getTentative())
  581. {
  582. value = spinctrl->get();
  583. if (mPanel->getTexFlipS()->get())
  584. {
  585. value = -value;
  586. }
  587. if (texgen->getCurrentIndex() == 1)
  588. {
  589. value *= 0.5f;
  590. }
  591. object->setTEScaleS(te, value);
  592. if (align_planar)
  593. {
  594. LLPanelFaceSetAlignedTEFunctor::setNormalRepeatX(mPanel, value,
  595. te);
  596. LLPanelFaceSetAlignedTEFunctor::setSpecularRepeatX(mPanel, value,
  597. te);
  598. }
  599. }
  600. spinctrl = mPanel->getTexScaleV();
  601. if (align_planar || !spinctrl->getTentative())
  602. {
  603. value = spinctrl->get();
  604. if (mPanel->getTexFlipT()->get())
  605. {
  606. value = -value;
  607. }
  608. if (texgen->getCurrentIndex() == 1)
  609. {
  610. value *= 0.5f;
  611. }
  612. object->setTEScaleT(te, value);
  613. if (align_planar)
  614. {
  615. LLPanelFaceSetAlignedTEFunctor::setNormalRepeatY(mPanel, value,
  616. te);
  617. LLPanelFaceSetAlignedTEFunctor::setSpecularRepeatY(mPanel, value,
  618. te);
  619. }
  620. }
  621. spinctrl = mPanel->getTexOffsetU();
  622. if (align_planar || !spinctrl->getTentative())
  623. {
  624. value = spinctrl->get();
  625. object->setTEOffsetS(te, value);
  626. if (align_planar)
  627. {
  628. LLPanelFaceSetAlignedTEFunctor::setNormalOffsetX(mPanel, value,
  629. te);
  630. LLPanelFaceSetAlignedTEFunctor::setSpecularOffsetX(mPanel, value,
  631. te);
  632. }
  633. }
  634. spinctrl = mPanel->getTexOffsetV();
  635. if (align_planar || !spinctrl->getTentative())
  636. {
  637. value = spinctrl->get();
  638. object->setTEOffsetT(te, value);
  639. if (align_planar)
  640. {
  641. LLPanelFaceSetAlignedTEFunctor::setNormalOffsetY(mPanel, value,
  642. te);
  643. LLPanelFaceSetAlignedTEFunctor::setSpecularOffsetY(mPanel, value,
  644. te);
  645. }
  646. }
  647. spinctrl = mPanel->getTexRot();
  648. if (align_planar || !spinctrl->getTentative())
  649. {
  650. value = spinctrl->get() * DEG_TO_RAD;
  651. object->setTERotation(te, value);
  652. if (align_planar)
  653. {
  654. LLPanelFaceSetAlignedTEFunctor::setNormalRotation(mPanel, value,
  655. te);
  656. LLPanelFaceSetAlignedTEFunctor::setSpecularRotation(mPanel, value,
  657. te);
  658. }
  659. }
  660. return true;
  661. }
  662. // Functor that tests if a face is aligned to mCenterFace
  663. struct LLPanelFaceGetIsAlignedTEFunctor final : public LLSelectedTEFunctor
  664. {
  665. LLPanelFaceGetIsAlignedTEFunctor(LLFace* center_facep)
  666. : mCenterFace(center_facep)
  667. {
  668. }
  669. bool apply(LLViewerObject* objectp, S32 te) override
  670. {
  671. LLFace* facep = objectp->mDrawable->getFace(te);
  672. if (!facep || !facep->getViewerObject() ||
  673. !facep->getViewerObject()->getVolume() ||
  674. facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
  675. {
  676. // Volume face does not exist, cannot be aligned
  677. return true;
  678. }
  679. if (facep == mCenterFace)
  680. {
  681. return true;
  682. }
  683. LLVector2 aligned_st_offset, aligned_st_scale;
  684. F32 aligned_st_rot;
  685. if (facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset,
  686. &aligned_st_scale, &aligned_st_rot))
  687. {
  688. const LLTextureEntry* tep = facep->getTextureEntry();
  689. if (!tep) return false;
  690. LLVector2 st_offset, st_scale;
  691. tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);
  692. tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);
  693. F32 st_rot = tep->getRotation();
  694. // Needs a fuzzy comparison, because of FP errors
  695. if (is_approx_equal_fraction(st_offset.mV[VX],
  696. aligned_st_offset.mV[VX], 12) &&
  697. is_approx_equal_fraction(st_offset.mV[VY],
  698. aligned_st_offset.mV[VY], 12) &&
  699. is_approx_equal_fraction(st_scale.mV[VX],
  700. aligned_st_scale.mV[VX], 12) &&
  701. is_approx_equal_fraction(st_scale.mV[VY],
  702. aligned_st_scale.mV[VY], 12) &&
  703. is_approx_equal_fraction(st_rot, aligned_st_rot, 6))
  704. {
  705. return true;
  706. }
  707. }
  708. return false;
  709. }
  710. private:
  711. LLFace* mCenterFace;
  712. };
  713. struct LLPanelFaceSendFunctor final : public LLSelectedObjectFunctor
  714. {
  715. bool apply(LLViewerObject* objectp) override
  716. {
  717. objectp->sendTEUpdate();
  718. return true;
  719. }
  720. };
  721. //virtual
  722. void LLPanelFace::refresh()
  723. {
  724. getState();
  725. }
  726. // This is for now only used to draw the material preview thumbnail, when
  727. // needed and possible. HB
  728. //virtual
  729. void LLPanelFace::draw()
  730. {
  731. // Let's avoid calling setText(getString(...)) at every frame.
  732. enum
  733. {
  734. NEEDS_PROBES = -3,
  735. NEEDS_PBR_MODE = -2,
  736. UNSET_PBR_LABEL = -1,
  737. NO_PBR_MAT = 0,
  738. LOADING_PBR_MAT = 1,
  739. HAS_PBR_MAT = 2,
  740. MULTIPLE_PBR_MAT = 3,
  741. };
  742. static S32 pbr_preview_label = UNSET_PBR_LABEL;
  743. // Draw all UI elements before we would draw the texture.
  744. LLPanel::draw();
  745. if (!mPbrThumbBorder->getVisible())
  746. {
  747. // Preview thumbnail square hidden, so nothing to draw.
  748. return;
  749. }
  750. if (!mPbrThumbBorder->getEnabled()) // Object not editable
  751. {
  752. if (pbr_preview_label != HAS_PBR_MAT)
  753. {
  754. pbr_preview_label = HAS_PBR_MAT;
  755. mLabelPbrPreview->setText(getString("base_material_text"));
  756. }
  757. }
  758. else if (!gUsePBRShaders)
  759. {
  760. if (pbr_preview_label != NEEDS_PBR_MODE)
  761. {
  762. pbr_preview_label = NEEDS_PBR_MODE;
  763. mLabelPbrPreview->setText(getString("needs_pbr_text"));
  764. }
  765. }
  766. // For now, material preview does not render at all when reflection probes
  767. // are disabled. *TODO: find out why and fix it.
  768. else if (!LLPipeline::sReflectionProbesEnabled)
  769. {
  770. if (pbr_preview_label != NEEDS_PROBES)
  771. {
  772. pbr_preview_label = NEEDS_PROBES;
  773. mLabelPbrPreview->setText(getString("needs_probes_text"));
  774. }
  775. }
  776. else if (mGLTFMaterial.isNull())
  777. {
  778. if (mHasMultiplePbrSelection)
  779. {
  780. if (pbr_preview_label != MULTIPLE_PBR_MAT)
  781. {
  782. pbr_preview_label = MULTIPLE_PBR_MAT;
  783. mLabelPbrPreview->setText(getString("multiple_mat_text"));
  784. }
  785. }
  786. else if (pbr_preview_label != NO_PBR_MAT)
  787. {
  788. pbr_preview_label = NO_PBR_MAT;
  789. mLabelPbrPreview->setText(getString("no_mat_text"));
  790. }
  791. }
  792. else if (mMatTexture.notNull())
  793. {
  794. if (pbr_preview_label != HAS_PBR_MAT)
  795. {
  796. pbr_preview_label = HAS_PBR_MAT;
  797. mLabelPbrPreview->setText(getString("base_material_text"));
  798. }
  799. gl_draw_scaled_image(mThumbnailRect.mLeft, mThumbnailRect.mBottom,
  800. mThumbnailRect.getWidth(),
  801. mThumbnailRect.getHeight(), mMatTexture);
  802. return; // It has been drawn now.
  803. }
  804. else // Material data/textures still loading
  805. {
  806. if (pbr_preview_label != LOADING_PBR_MAT)
  807. {
  808. pbr_preview_label = LOADING_PBR_MAT;
  809. mLabelPbrPreview->setText(getString("loading_mat_text"));
  810. }
  811. // Try and see if it is ready now...
  812. mMatTexture = LLGLTFPreviewTexture::getPreview(mGLTFMaterial);
  813. }
  814. // Not in PBR mode, or no reflection probes, or material preview not ready,
  815. // or material not unique: draw a grey square.
  816. gl_rect_2d(mThumbnailRect, LLColor4::grey);
  817. }
  818. LLFace* LLPanelFace::getLastSelectedFace()
  819. {
  820. struct get_last_face_func final : public LLSelectedTEGetFunctor<LLFace*>
  821. {
  822. LLFace* get(LLViewerObject* objectp, S32 te) override
  823. {
  824. LLDrawable* drawablep = objectp->mDrawable;
  825. return drawablep ? drawablep->getFace(te) : NULL;
  826. }
  827. } func;
  828. LLFace* last_facep = NULL;
  829. gSelectMgr.getSelection()->getSelectedTEValue(&func, last_facep);
  830. return last_facep;
  831. }
  832. void LLPanelFace::getState()
  833. {
  834. static LLUUID last_selected_object_id;
  835. static LLUUID last_pbr_id;
  836. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  837. LLViewerObject* objectp = selection->getFirstObject();
  838. if (objectp && objectp->getPCode() == LL_PCODE_VOLUME &&
  839. (objectp->permModify() || gAgent.isGodlikeWithoutAdminMenuFakery()))
  840. {
  841. bool is_attachment = objectp->isAttachment();
  842. bool editable = objectp->permModify() &&
  843. !objectp->isPermanentEnforced();
  844. mLabelMaps->setEnabled(editable);
  845. mMapsRadio->setEnabled(editable);
  846. // Do we have PBR mat support ?
  847. bool has_pbr_mat = gAgent.hasInventoryMaterial();
  848. mButtonLocalPBR->setEnabled(editable && has_pbr_mat);
  849. mButtonLoadPBR->setEnabled(editable && has_pbr_mat);
  850. bool identical = false;
  851. // Any PBR material on selected faces ?
  852. mHasMultiplePbrSelection = false;
  853. if (has_pbr_mat)
  854. {
  855. struct pbr_id_get final : public LLSelectedTEGetFunctor<LLUUID>
  856. {
  857. LLUUID get(LLViewerObject* objectp, S32 face) override
  858. {
  859. const LLUUID& mat_id = objectp->getRenderMaterialID(face);
  860. if (mat_id.notNull())
  861. {
  862. has_mat = true;
  863. }
  864. return objectp->getRenderMaterialID(face);
  865. }
  866. bool has_mat = false;
  867. } func;
  868. LLUUID pbr_id;
  869. identical = selection->getSelectedTEValue(&func, pbr_id);
  870. has_pbr_mat = pbr_id.notNull();
  871. mHasMultiplePbrSelection = func.has_mat && !identical;
  872. if (has_pbr_mat && identical)
  873. {
  874. mGLTFMaterial = gGLTFMaterialList.getMaterial(pbr_id);
  875. mMatTexture = LLGLTFPreviewTexture::getPreview(mGLTFMaterial);
  876. }
  877. }
  878. if (!has_pbr_mat || !identical)
  879. {
  880. mMatTexture = NULL;
  881. mGLTFMaterial = NULL;
  882. LLPreviewMaterial::closeLiveEditorInstance();
  883. }
  884. mLabelPbrPreview->setEnabled(editable);
  885. mButtonEditPBR->setEnabled(editable && has_pbr_mat && identical &&
  886. LLPreviewMaterial::canModifyObjectsMaterial());
  887. mButtonSavePBR->setEnabled(editable && has_pbr_mat && identical &&
  888. LLPreviewMaterial::canSaveObjectsMaterial());
  889. // Texture
  890. bool identical_diffuse;
  891. LLUUID id;
  892. {
  893. struct tex_get final : public LLSelectedTEGetFunctor<LLUUID>
  894. {
  895. LLUUID get(LLViewerObject* objectp, S32 face) override
  896. {
  897. LLTextureEntry* tep = objectp->getTE(face);
  898. const LLUUID& te_id = tep ? tep->getID() : LLUUID::null;
  899. if (tep &&
  900. LLAvatarAppearanceDictionary::isBakedImageId(te_id))
  901. {
  902. return te_id;
  903. }
  904. LLViewerTexture* imagep = objectp->getTEImage(face);
  905. const LLUUID& id = imagep ? imagep->getID() : LLUUID::null;
  906. if (id.notNull() && te_id.notNull() &&
  907. LLViewerMedia::textureHasMedia(id))
  908. {
  909. LLViewerTexture* texp = gTextureList.findImage(te_id);
  910. if (!texp)
  911. {
  912. texp = LLViewerFetchedTexture::sDefaultImagep;
  913. }
  914. if (texp)
  915. {
  916. return texp->getID();
  917. }
  918. }
  919. return id;
  920. }
  921. } func;
  922. identical_diffuse = selection->getSelectedTEValue(&func, id);
  923. }
  924. mTextureCtrl->setTentative(!identical_diffuse);
  925. mTextureCtrl->setEnabled(editable);
  926. mTextureCtrl->setImageAssetID(id);
  927. mTextureCtrl->setBakeTextureEnabled(editable);
  928. if (is_attachment)
  929. {
  930. mTextureCtrl->setImmediateFilterPermMask(PERM_COPY |
  931. PERM_TRANSFER);
  932. }
  933. else
  934. {
  935. mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
  936. }
  937. // Only turn on auto-align button if there is a media renderer and the
  938. // media is loaded
  939. bool has_media = LLViewerMedia::textureHasMedia(id);
  940. mButtonAlignMedia->setEnabled(editable && has_media);
  941. mLabelMedia->setEnabled(editable);
  942. LLAggregatePermissions texture_perms;
  943. if (gSelectMgr.selectGetAggregateTexturePermissions(texture_perms))
  944. {
  945. bool can_copy = texture_perms.getValue(PERM_COPY) ==
  946. LLAggregatePermissions::AP_EMPTY ||
  947. texture_perms.getValue(PERM_COPY) ==
  948. LLAggregatePermissions::AP_ALL;
  949. bool can_transfer = texture_perms.getValue(PERM_TRANSFER) ==
  950. LLAggregatePermissions::AP_EMPTY ||
  951. texture_perms.getValue(PERM_TRANSFER) ==
  952. LLAggregatePermissions::AP_ALL;
  953. mTextureCtrl->setCanApplyImmediately(can_copy && can_transfer);
  954. }
  955. else
  956. {
  957. mTextureCtrl->setCanApplyImmediately(false);
  958. }
  959. // Color swatch
  960. LLColor4 color = LLColor4::white;
  961. {
  962. struct color_get final : public LLSelectedTEGetFunctor<LLColor4>
  963. {
  964. LLColor4 get(LLViewerObject* objectp, S32 face) override
  965. {
  966. LLTextureEntry* tep = objectp->getTE(face);
  967. return tep ? tep->getColor() : LLColor4::white;
  968. }
  969. } func;
  970. identical = selection->getSelectedTEValue(&func, color);
  971. }
  972. mLabelDiffuseColor->setEnabled(editable);
  973. LLColor4 prev_color = mColorSwatch->get();
  974. mColorSwatch->setOriginal(color);
  975. mColorSwatch->set(color, !editable || prev_color != color);
  976. mColorSwatch->setValid(editable);
  977. mColorSwatch->setEnabled(editable);
  978. mColorSwatch->setCanApplyImmediately(editable);
  979. mColorSwatch->setFallbackImageName("materials_ui_x_24.png");
  980. // Transparency
  981. mLabelColorTransp->setEnabled(editable);
  982. F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
  983. mTransparency->setValue(editable ? transparency : 0.f);
  984. mTransparency->setEnabled(editable);
  985. // Alpha channel
  986. GLenum image_format = 0;
  987. {
  988. struct image_format_get final
  989. : public LLSelectedTEGetFunctor<GLenum>
  990. {
  991. GLenum get(LLViewerObject* objectp, S32 face) override
  992. {
  993. GLenum image_format = GL_RGB;
  994. LLViewerTexture* imagep = objectp->getTEImage(face);
  995. if (imagep)
  996. {
  997. image_format = imagep->getPrimaryFormat();
  998. }
  999. return image_format;
  1000. }
  1001. } func;
  1002. identical = selection->getSelectedTEValue(&func, image_format);
  1003. }
  1004. switch (image_format)
  1005. {
  1006. case GL_RGBA:
  1007. case GL_ALPHA:
  1008. {
  1009. mIsAlpha = true;
  1010. break;
  1011. }
  1012. case GL_RGB:
  1013. {
  1014. mIsAlpha = false;
  1015. break;
  1016. }
  1017. default:
  1018. {
  1019. llwarns << "Unexpected texture format: resorting to no alpha."
  1020. << llendl;
  1021. mIsAlpha = false;
  1022. }
  1023. }
  1024. // Alpha mode
  1025. U8 alpha_mode;
  1026. {
  1027. struct alpha_get final : public LLSelectedTEGetFunctor<U8>
  1028. {
  1029. U8 get(LLViewerObject* objectp, S32 te_index) override
  1030. {
  1031. U8 ret = 1;
  1032. LLTextureEntry* tep = objectp->getTE(te_index);
  1033. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1034. : NULL;
  1035. if (matp)
  1036. {
  1037. ret = matp->getDiffuseAlphaMode();
  1038. }
  1039. return ret;
  1040. }
  1041. } func;
  1042. identical = selection->getSelectedTEValue(&func, alpha_mode);
  1043. }
  1044. if (transparency > 0.f || has_pbr_mat)
  1045. {
  1046. // It is invalid to have any alpha mode other than blend if
  1047. // transparency is greater than zero or a PBR material is
  1048. // present...
  1049. // Note: alpha blend with PBR material only works for 0% and 100%
  1050. // transparency values (anything below 100% behaves like 0%). HB
  1051. alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
  1052. }
  1053. if (!mIsAlpha || has_pbr_mat)
  1054. {
  1055. // ... unless there is no alpha channel in the texture, in which
  1056. // case alpha mode MUST be none.
  1057. alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
  1058. }
  1059. mComboAlphaMode->setCurrentByIndex(alpha_mode);
  1060. mComboAlphaMode->setTentative(!identical);
  1061. mComboAlphaMode->setEnabled(!has_pbr_mat);
  1062. updateAlphaControls();
  1063. // Normal map (and legacy material presence)
  1064. bool identical_norm;
  1065. LLUUID normmap_id;
  1066. {
  1067. struct norm_get final : public LLSelectedTEGetFunctor<LLUUID>
  1068. {
  1069. LLUUID get(LLViewerObject* objectp, S32 te_index) override
  1070. {
  1071. LLUUID id;
  1072. LLTextureEntry* tep = objectp->getTE(te_index);
  1073. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1074. : NULL;
  1075. if (matp)
  1076. {
  1077. id = matp->getNormalID();
  1078. }
  1079. return id;
  1080. }
  1081. } func;
  1082. identical_norm = selection->getSelectedTEValue(&func, normmap_id);
  1083. }
  1084. mNormalCtrl->setTentative(!identical_norm);
  1085. mNormalCtrl->setEnabled(editable);
  1086. mNormalCtrl->setImageAssetID(normmap_id);
  1087. mNormalCtrl->setFallbackImageName("materials_ui_x_24.png");
  1088. if (is_attachment)
  1089. {
  1090. mNormalCtrl->setImmediateFilterPermMask(PERM_COPY |
  1091. PERM_TRANSFER);
  1092. }
  1093. else
  1094. {
  1095. mNormalCtrl->setImmediateFilterPermMask(PERM_NONE);
  1096. }
  1097. mMapsRadio->setIndexEnabled(MATTYPE_PBR,
  1098. editable &&
  1099. gAgent.hasInventoryMaterial());
  1100. // Specular map
  1101. bool identical_spec;
  1102. LLUUID specmap_id;
  1103. {
  1104. struct spec_get final : public LLSelectedTEGetFunctor<LLUUID>
  1105. {
  1106. LLUUID get(LLViewerObject* objectp, S32 te_index) override
  1107. {
  1108. LLUUID id;
  1109. LLTextureEntry* tep = objectp->getTE(te_index);
  1110. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1111. : NULL;
  1112. if (matp)
  1113. {
  1114. id = matp->getSpecularID();
  1115. }
  1116. return id;
  1117. }
  1118. } func;
  1119. identical_spec = selection->getSelectedTEValue(&func, specmap_id);
  1120. }
  1121. mSpecularCtrl->setTentative(!identical_spec);
  1122. mSpecularCtrl->setEnabled(editable);
  1123. mSpecularCtrl->setImageAssetID(specmap_id);
  1124. mSpecularCtrl->setFallbackImageName("materials_ui_x_24.png");
  1125. if (is_attachment)
  1126. {
  1127. mSpecularCtrl->setImmediateFilterPermMask(PERM_COPY |
  1128. PERM_TRANSFER);
  1129. }
  1130. else
  1131. {
  1132. mSpecularCtrl->setImmediateFilterPermMask(PERM_NONE);
  1133. }
  1134. mShinyColorSwatch->setFallbackImageName("materials_ui_x_24.png");
  1135. // Planar align
  1136. bool align_planar = mCheckPlanarAlign->get();
  1137. bool identical_planar_aligned = false;
  1138. bool is_planar = false;
  1139. bool enabled;
  1140. {
  1141. struct planar_get final : public LLSelectedTEGetFunctor<bool>
  1142. {
  1143. bool get(LLViewerObject* objectp, S32 face) override
  1144. {
  1145. LLTextureEntry* tep = objectp->getTE(face);
  1146. return tep &&
  1147. tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR;
  1148. }
  1149. } func1;
  1150. bool texgens_identical = selection->getSelectedTEValue(&func1,
  1151. is_planar);
  1152. enabled = editable && texgens_identical && is_planar;
  1153. if (align_planar && enabled)
  1154. {
  1155. LLFace* last_face = getLastSelectedFace();
  1156. LLPanelFaceGetIsAlignedTEFunctor get_is_aligned_func(last_face);
  1157. // This will determine if the texture param controls are tentative:
  1158. identical_planar_aligned =
  1159. selection->applyToTEs(&get_is_aligned_func);
  1160. }
  1161. }
  1162. if (!enabled)
  1163. {
  1164. align_planar = false;
  1165. }
  1166. mCheckPlanarAlign->setValue(align_planar);
  1167. mCheckPlanarAlign->setEnabled(enabled);
  1168. LLTextureEntry::e_texgen selected_texgen =
  1169. LLTextureEntry::TEX_GEN_DEFAULT;
  1170. bool identical_planar_texgen;
  1171. {
  1172. bool identical_texgen;
  1173. struct texgen_get final
  1174. : public LLSelectedTEGetFunctor<LLTextureEntry::e_texgen>
  1175. {
  1176. LLTextureEntry::e_texgen get(LLViewerObject* objectp,
  1177. S32 face) override
  1178. {
  1179. LLTextureEntry* tep = objectp->getTE(face);
  1180. return tep ? (LLTextureEntry::e_texgen)tep->getTexGen()
  1181. : LLTextureEntry::TEX_GEN_DEFAULT;
  1182. }
  1183. } func;
  1184. identical_texgen = selection->getSelectedTEValue(&func, selected_texgen);
  1185. identical_planar_texgen = identical_texgen &&
  1186. selected_texgen == LLTextureEntry::TEX_GEN_PLANAR;
  1187. }
  1188. F32 scale_factor = identical_planar_texgen ? 2.f : 1.f;
  1189. // Texture scale
  1190. mLabelTexScale->setEnabled(editable);
  1191. mLabelTexScaleUnit->setEnabled(editable);
  1192. mLabelTexScaleHoriz->setEnabled(editable);
  1193. mLabelTexScaleVert->setEnabled(editable);
  1194. F32 scale_s = 1.f;
  1195. {
  1196. struct tex_scale_s_get final : public LLSelectedTEGetFunctor<F32>
  1197. {
  1198. F32 get(LLViewerObject* objectp, S32 face) override
  1199. {
  1200. LLTextureEntry* tep = objectp->getTE(face);
  1201. return tep ? tep->getScaleS() : 0.f;
  1202. }
  1203. } func;
  1204. identical = selection->getSelectedTEValue(&func, scale_s, 0.001f);
  1205. }
  1206. identical = align_planar ? identical_planar_aligned : identical;
  1207. F32 scale = editable ? fabsf(scale_factor * scale_s) : 0.f;
  1208. mTexScaleU->setValue(scale);
  1209. mTexScaleU->setTentative(!identical);
  1210. mTexScaleU->setEnabled(editable);
  1211. mCheckTexFlipS->setValue(LLSD(scale_s < 0));
  1212. mCheckTexFlipS->setTentative(!identical);
  1213. mCheckTexFlipS->setEnabled(editable);
  1214. F32 scale_t = 1.f;
  1215. {
  1216. struct tex_scale_t_get final : public LLSelectedTEGetFunctor<F32>
  1217. {
  1218. F32 get(LLViewerObject* objectp, S32 face) override
  1219. {
  1220. LLTextureEntry* tep = objectp->getTE(face);
  1221. return tep ? tep->getScaleT() : 0.f;
  1222. }
  1223. } func;
  1224. identical = selection->getSelectedTEValue(&func, scale_t, 0.001f);
  1225. }
  1226. identical = align_planar ? identical_planar_aligned : identical;
  1227. scale = editable ? fabsf(scale_factor * scale_t) : 0.f;
  1228. mTexScaleV->setValue(scale);
  1229. mTexScaleV->setTentative(!identical);
  1230. mTexScaleV->setEnabled(editable);
  1231. mCheckTexFlipT->setValue(LLSD(scale_t < 0));
  1232. mCheckTexFlipT->setTentative(!identical);
  1233. mCheckTexFlipT->setEnabled(editable);
  1234. // Texture offset
  1235. mLabelTexOffset->setEnabled(editable);
  1236. mLabelTexOffsetHoriz->setEnabled(editable);
  1237. mLabelTexOffsetVert->setEnabled(editable);
  1238. F32 offset_s = 0.f;
  1239. {
  1240. struct tex_offset_s_get final : public LLSelectedTEGetFunctor<F32>
  1241. {
  1242. F32 get(LLViewerObject* objectp, S32 face) override
  1243. {
  1244. LLTextureEntry* tep = objectp->getTE(face);
  1245. return tep ? tep->getOffsetS() : 0.f;
  1246. }
  1247. } func;
  1248. identical = selection->getSelectedTEValue(&func, offset_s, 0.001f);
  1249. }
  1250. identical = align_planar ? identical_planar_aligned : identical;
  1251. mTexOffsetU->setValue(editable ? offset_s : 0.f);
  1252. mTexOffsetU->setTentative(!identical);
  1253. mTexOffsetU->setEnabled(editable);
  1254. F32 offset_t = 0.f;
  1255. {
  1256. struct tex_offset_t_get final : public LLSelectedTEGetFunctor<F32>
  1257. {
  1258. F32 get(LLViewerObject* objectp, S32 face) override
  1259. {
  1260. LLTextureEntry* tep = objectp->getTE(face);
  1261. return tep ? tep->getOffsetT() : 0.f;
  1262. }
  1263. } func;
  1264. identical = selection->getSelectedTEValue(&func, offset_t, 0.001f);
  1265. }
  1266. identical = align_planar ? identical_planar_aligned : identical;
  1267. mTexOffsetV->setValue(editable ? offset_t : 0.f);
  1268. mTexOffsetV->setTentative(!identical);
  1269. mTexOffsetV->setEnabled(editable);
  1270. // Texture rotation
  1271. mLabelTexRotate->setEnabled(editable);
  1272. F32 rotation = 0.f;
  1273. {
  1274. struct tex_rot_get final : public LLSelectedTEGetFunctor<F32>
  1275. {
  1276. F32 get(LLViewerObject* objectp, S32 face) override
  1277. {
  1278. LLTextureEntry* tep = objectp->getTE(face);
  1279. return tep ? tep->getRotation() : 0.f;
  1280. }
  1281. } func;
  1282. identical = selection->getSelectedTEValue(&func, rotation, 0.001f);
  1283. }
  1284. identical = align_planar ? identical_planar_aligned : identical;
  1285. mTexRot->setValue(editable ? rotation * RAD_TO_DEG : 0.f);
  1286. mTexRot->setTentative(!identical);
  1287. mTexRot->setEnabled(editable);
  1288. // Nomal map scale
  1289. {
  1290. struct bump_scale_s_get final : public LLSelectedTEGetFunctor<F32>
  1291. {
  1292. F32 get(LLViewerObject* objectp, S32 face) override
  1293. {
  1294. F32 s = 1.f;
  1295. LLTextureEntry* tep = objectp->getTE(face);
  1296. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1297. : NULL;
  1298. if (matp)
  1299. {
  1300. F32 t = 0.f;
  1301. matp->getNormalRepeat(s, t);
  1302. }
  1303. return s;
  1304. }
  1305. } func;
  1306. identical = selection->getSelectedTEValue(&func, scale_s, 0.001f);
  1307. }
  1308. identical = align_planar ? identical_planar_aligned : identical;
  1309. scale = editable ? fabsf(scale_factor * scale_s) : 0.f;
  1310. mBumpyScaleU->setValue(scale);
  1311. mBumpyScaleU->setTentative(!identical);
  1312. mBumpyScaleU->setEnabled(editable && normmap_id.notNull());
  1313. mCheckBumpyFlipS->setValue(LLSD(scale_s < 0));
  1314. mCheckBumpyFlipS->setTentative(!identical);
  1315. mCheckBumpyFlipS->setEnabled(editable && normmap_id.notNull());
  1316. {
  1317. struct bump_scale_t_get final : public LLSelectedTEGetFunctor<F32>
  1318. {
  1319. F32 get(LLViewerObject* objectp, S32 face) override
  1320. {
  1321. F32 t = 1.f;
  1322. LLTextureEntry* tep = objectp->getTE(face);
  1323. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1324. : NULL;
  1325. if (matp)
  1326. {
  1327. F32 s = 0.f;
  1328. matp->getNormalRepeat(s, t);
  1329. }
  1330. return t;
  1331. }
  1332. } func;
  1333. identical = selection->getSelectedTEValue(&func, scale_t, 0.001f);
  1334. }
  1335. identical = align_planar ? identical_planar_aligned : identical;
  1336. scale = editable ? fabsf(scale_factor * scale_t) : 0.f;
  1337. mBumpyScaleV->setValue(scale);
  1338. mBumpyScaleV->setTentative(!identical);
  1339. mBumpyScaleV->setEnabled(editable && normmap_id.notNull());
  1340. mCheckBumpyFlipT->setValue(LLSD(scale_t < 0));
  1341. mCheckBumpyFlipT->setTentative(!identical);
  1342. mCheckBumpyFlipT->setEnabled(editable && normmap_id.notNull());
  1343. // Normal map offset
  1344. {
  1345. struct bump_offset_s_get final : public LLSelectedTEGetFunctor<F32>
  1346. {
  1347. F32 get(LLViewerObject* objectp, S32 face) override
  1348. {
  1349. F32 s = 0.f;
  1350. LLTextureEntry* tep = objectp->getTE(face);
  1351. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1352. : NULL;
  1353. if (matp)
  1354. {
  1355. F32 t = 0.f;
  1356. matp->getNormalOffset(s, t);
  1357. }
  1358. return s;
  1359. }
  1360. } func;
  1361. identical = selection->getSelectedTEValue(&func, offset_s, 0.001f);
  1362. }
  1363. identical = align_planar ? identical_planar_aligned : identical;
  1364. mBumpyOffsetU->setValue(editable ? offset_s : 0.f);
  1365. mBumpyOffsetU->setTentative(!identical);
  1366. mBumpyOffsetU->setEnabled(editable && normmap_id.notNull());
  1367. {
  1368. struct bump_offset_t_get final : public LLSelectedTEGetFunctor<F32>
  1369. {
  1370. F32 get(LLViewerObject* objectp, S32 face) override
  1371. {
  1372. F32 t = 0.f;
  1373. LLTextureEntry* tep = objectp->getTE(face);
  1374. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1375. : NULL;
  1376. if (matp)
  1377. {
  1378. F32 s = 0.f;
  1379. matp->getNormalOffset(s, t);
  1380. }
  1381. return t;
  1382. }
  1383. } func;
  1384. identical = selection->getSelectedTEValue(&func, offset_t, 0.001f);
  1385. }
  1386. identical = align_planar ? identical_planar_aligned : identical;
  1387. mBumpyOffsetV->setValue(editable ? offset_t : 0.f);
  1388. mBumpyOffsetV->setTentative(!identical);
  1389. mBumpyOffsetV->setEnabled(editable && normmap_id.notNull());
  1390. // Normal map rotation
  1391. {
  1392. struct bump_rot_get final : public LLSelectedTEGetFunctor<F32>
  1393. {
  1394. F32 get(LLViewerObject* objectp, S32 face) override
  1395. {
  1396. F32 ret = 0.f;
  1397. LLTextureEntry* tep = objectp->getTE(face);
  1398. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1399. : NULL;
  1400. if (matp)
  1401. {
  1402. ret = matp->getNormalRotation();
  1403. }
  1404. return ret;
  1405. }
  1406. } func;
  1407. identical = selection->getSelectedTEValue(&func, rotation, 0.001f);
  1408. }
  1409. identical = align_planar ? identical_planar_aligned : identical;
  1410. mBumpyRot->setValue(editable ? rotation * RAD_TO_DEG : 0.f);
  1411. mBumpyRot->setTentative(!identical);
  1412. mBumpyRot->setEnabled(editable && normmap_id.notNull());
  1413. // Specular map scale
  1414. {
  1415. struct shiny_scale_s_get final : public LLSelectedTEGetFunctor<F32>
  1416. {
  1417. F32 get(LLViewerObject* objectp, S32 face) override
  1418. {
  1419. F32 s = 1.f;
  1420. LLTextureEntry* tep = objectp->getTE(face);
  1421. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1422. : NULL;
  1423. if (matp)
  1424. {
  1425. F32 t = 0.f;
  1426. matp->getSpecularRepeat(s, t);
  1427. }
  1428. return s;
  1429. }
  1430. } func;
  1431. identical = selection->getSelectedTEValue(&func, scale_s, 0.001f);
  1432. }
  1433. identical = align_planar ? identical_planar_aligned : identical;
  1434. scale = editable ? fabsf(scale_factor * scale_s) : 0.f;
  1435. mShinyScaleU->setValue(scale);
  1436. mShinyScaleU->setTentative(!identical);
  1437. mShinyScaleU->setEnabled(editable && specmap_id.notNull());
  1438. mCheckShinyFlipS->setValue(LLSD(scale_s < 0));
  1439. mCheckShinyFlipS->setTentative(!identical);
  1440. mCheckShinyFlipS->setEnabled(editable && specmap_id.notNull());
  1441. {
  1442. struct shiny_scale_t_get final : public LLSelectedTEGetFunctor<F32>
  1443. {
  1444. F32 get(LLViewerObject* objectp, S32 face) override
  1445. {
  1446. F32 t = 1.f;
  1447. LLTextureEntry* tep = objectp->getTE(face);
  1448. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1449. : NULL;
  1450. if (matp)
  1451. {
  1452. F32 s = 0.f;
  1453. matp->getSpecularRepeat(s, t);
  1454. }
  1455. return t;
  1456. }
  1457. } func;
  1458. identical = selection->getSelectedTEValue(&func, scale_t, 0.001f);
  1459. }
  1460. identical = align_planar ? identical_planar_aligned : identical;
  1461. scale = editable ? fabsf(scale_factor * scale_t) : 0.f;
  1462. mShinyScaleV->setValue(scale);
  1463. mShinyScaleV->setTentative(!identical);
  1464. mShinyScaleV->setEnabled(editable && specmap_id.notNull());
  1465. mCheckShinyFlipT->setValue(LLSD(scale_t < 0));
  1466. mCheckShinyFlipT->setTentative(!identical);
  1467. mCheckShinyFlipT->setEnabled(editable && specmap_id.notNull());
  1468. // Specular map offset
  1469. {
  1470. struct shiny_offset_s_get final
  1471. : public LLSelectedTEGetFunctor<F32>
  1472. {
  1473. F32 get(LLViewerObject* objectp, S32 face) override
  1474. {
  1475. F32 s = 0.f;
  1476. LLTextureEntry* tep = objectp->getTE(face);
  1477. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1478. : NULL;
  1479. if (matp)
  1480. {
  1481. F32 t = 0.f;
  1482. matp->getSpecularOffset(s, t);
  1483. }
  1484. return s;
  1485. }
  1486. } func;
  1487. identical = selection->getSelectedTEValue(&func, offset_s, 0.001f);
  1488. }
  1489. identical = align_planar ? identical_planar_aligned : identical;
  1490. mShinyOffsetU->setValue(editable ? offset_s : 0.f);
  1491. mShinyOffsetU->setTentative(!identical);
  1492. mShinyOffsetU->setEnabled(editable && specmap_id.notNull());
  1493. {
  1494. struct shiny_offset_t_get final
  1495. : public LLSelectedTEGetFunctor<F32>
  1496. {
  1497. F32 get(LLViewerObject* objectp, S32 face) override
  1498. {
  1499. F32 t = 0.f;
  1500. LLTextureEntry* tep = objectp->getTE(face);
  1501. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1502. : NULL;
  1503. if (matp)
  1504. {
  1505. F32 s = 0.f;
  1506. matp->getSpecularOffset(s, t);
  1507. }
  1508. return t;
  1509. }
  1510. } func;
  1511. identical = selection->getSelectedTEValue(&func, offset_t, 0.001f);
  1512. }
  1513. identical = align_planar ? identical_planar_aligned : identical;
  1514. mShinyOffsetV->setValue(editable ? offset_t : 0.f);
  1515. mShinyOffsetV->setTentative(!identical);
  1516. mShinyOffsetV->setEnabled(editable && specmap_id.notNull());
  1517. // Specular map rotation
  1518. {
  1519. struct shiny_rot_get final : public LLSelectedTEGetFunctor<F32>
  1520. {
  1521. F32 get(LLViewerObject* objectp, S32 face) override
  1522. {
  1523. F32 ret = 0.f;
  1524. LLTextureEntry* tep = objectp->getTE(face);
  1525. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1526. : NULL;
  1527. if (matp)
  1528. {
  1529. ret = matp->getSpecularRotation();
  1530. }
  1531. return ret;
  1532. }
  1533. } func;
  1534. identical = selection->getSelectedTEValue(&func, rotation, 0.001f);
  1535. }
  1536. identical = align_planar ? identical_planar_aligned : identical;
  1537. mShinyRot->setValue(editable ? rotation * RAD_TO_DEG : 0.f);
  1538. mShinyRot->setTentative(!identical);
  1539. mShinyRot->setEnabled(editable && specmap_id.notNull());
  1540. // Glow
  1541. F32 glow = 0.f;
  1542. {
  1543. struct glow_get final : public LLSelectedTEGetFunctor<F32>
  1544. {
  1545. F32 get(LLViewerObject* objectp, S32 face) override
  1546. {
  1547. LLTextureEntry* tep = objectp->getTE(face);
  1548. return tep ? tep->getGlow() : 0.f;
  1549. }
  1550. } func;
  1551. identical = selection->getSelectedTEValue(&func, glow, 0.001f);
  1552. }
  1553. mGlow->setValue(glow);
  1554. mGlow->setEnabled(editable);
  1555. mGlow->setTentative(!identical);
  1556. // Shiny
  1557. mLabelShininess->setEnabled(editable);
  1558. U8 shiny = 0;
  1559. {
  1560. struct shiny_get final : public LLSelectedTEGetFunctor<U8>
  1561. {
  1562. U8 get(LLViewerObject* objectp, S32 face) override
  1563. {
  1564. LLTextureEntry* tep = objectp->getTE(face);
  1565. return tep ? tep->getShiny() : 0;
  1566. }
  1567. } func;
  1568. identical = selection->getSelectedTEValue(&func, shiny);
  1569. }
  1570. if (specmap_id.notNull())
  1571. {
  1572. shiny = SHINY_TEXTURE;
  1573. }
  1574. LL_DEBUGS("Materials") << "Specular map texture: " << specmap_id
  1575. << " - Shininess index: " << (S32)shiny
  1576. << LL_ENDL;
  1577. // Do not attempt to set the combo to SHINY_TEXTURE if the "Use
  1578. // Texture" entry does not exist (in which case updateShinyControls()
  1579. // will automatically create the entry and select it later for us).
  1580. if (shiny != SHINY_TEXTURE ||
  1581. mComboShininess->itemExists(mUseTextureText))
  1582. {
  1583. mComboShininess->setCurrentByIndex((S32)shiny);
  1584. }
  1585. mComboShininess->setEnabled(editable);
  1586. mComboShininess->setTentative(!identical);
  1587. mShinyColorSwatch->setTentative(!identical);
  1588. mGlossiness->setTentative(!identical);
  1589. mEnvironment->setTentative(!identical);
  1590. updateShinyControls();
  1591. // PBR material scale
  1592. if (has_pbr_mat)
  1593. {
  1594. struct pbr_scale_s_get final : public LLSelectedTEGetFunctor<F32>
  1595. {
  1596. F32 get(LLViewerObject* objectp, S32 face) override
  1597. {
  1598. F32 s = 1.f;
  1599. LLTextureEntry* tep = objectp->getTE(face);
  1600. LLGLTFMaterial* matp = tep ? tep->getGLTFMaterialOverride()
  1601. : NULL;
  1602. if (matp)
  1603. {
  1604. // *NOTE: here, we cheat and assume that all scales are
  1605. // equal for all PBR texture maps. *TODO: see if it is
  1606. // a problem at all (probably not)... HB
  1607. s = matp->mTextureTransform[0].mScale.mV[VX];
  1608. }
  1609. return s;
  1610. }
  1611. } func;
  1612. identical = selection->getSelectedTEValue(&func, scale_s, 0.001f);
  1613. identical = align_planar ? identical_planar_aligned : identical;
  1614. scale = editable ? fabsf(scale_factor * scale_s) : 0.f;
  1615. mPbrScaleU->setValue(scale);
  1616. mPbrScaleU->setTentative(!identical);
  1617. }
  1618. mPbrScaleU->setEnabled(editable && has_pbr_mat);
  1619. if (has_pbr_mat)
  1620. {
  1621. struct pbr_scale_t_get final : public LLSelectedTEGetFunctor<F32>
  1622. {
  1623. F32 get(LLViewerObject* objectp, S32 face) override
  1624. {
  1625. F32 s = 1.f;
  1626. LLTextureEntry* tep = objectp->getTE(face);
  1627. LLGLTFMaterial* matp = tep ? tep->getGLTFMaterialOverride()
  1628. : NULL;
  1629. if (matp)
  1630. {
  1631. // *NOTE: here, we cheat and assume that all scales are
  1632. // equal for all PBR texture maps. *TODO: see if it is
  1633. // a problem at all (probably not)... HB
  1634. s = matp->mTextureTransform[0].mScale.mV[VY];
  1635. }
  1636. return s;
  1637. }
  1638. } func;
  1639. identical = selection->getSelectedTEValue(&func, scale_t, 0.001f);
  1640. identical = align_planar ? identical_planar_aligned : identical;
  1641. scale = editable ? fabsf(scale_factor * scale_t) : 0.f;
  1642. mPbrScaleV->setValue(scale);
  1643. mPbrScaleV->setTentative(!identical);
  1644. }
  1645. mPbrScaleV->setEnabled(editable && has_pbr_mat);
  1646. // PBR material offset
  1647. if (has_pbr_mat)
  1648. {
  1649. struct pbr_offset_s_get final : public LLSelectedTEGetFunctor<F32>
  1650. {
  1651. F32 get(LLViewerObject* objectp, S32 face) override
  1652. {
  1653. F32 s = 1.f;
  1654. LLTextureEntry* tep = objectp->getTE(face);
  1655. LLGLTFMaterial* matp = tep ? tep->getGLTFMaterialOverride()
  1656. : NULL;
  1657. if (matp)
  1658. {
  1659. // *NOTE: here, we cheat and assume that all scales are
  1660. // equal for all PBR texture maps. *TODO: see if it is
  1661. // a problem at all (probably not)... HB
  1662. s = matp->mTextureTransform[0].mOffset.mV[VX];
  1663. }
  1664. return s;
  1665. }
  1666. } func;
  1667. identical = selection->getSelectedTEValue(&func, offset_s, 0.001f);
  1668. identical = align_planar ? identical_planar_aligned : identical;
  1669. mPbrOffsetU->setValue(editable ? offset_s : 0.f);
  1670. mPbrOffsetU->setTentative(!identical);
  1671. }
  1672. mPbrOffsetU->setEnabled(editable && has_pbr_mat);
  1673. if (has_pbr_mat)
  1674. {
  1675. struct pbr_offset_t_get final : public LLSelectedTEGetFunctor<F32>
  1676. {
  1677. F32 get(LLViewerObject* objectp, S32 face) override
  1678. {
  1679. F32 s = 1.f;
  1680. LLTextureEntry* tep = objectp->getTE(face);
  1681. LLGLTFMaterial* matp = tep ? tep->getGLTFMaterialOverride()
  1682. : NULL;
  1683. if (matp)
  1684. {
  1685. // *NOTE: here, we cheat and assume that all scales are
  1686. // equal for all PBR texture maps. *TODO: see if it is
  1687. // a problem at all (probably not)... HB
  1688. s = matp->mTextureTransform[0].mOffset.mV[VY];
  1689. }
  1690. return s;
  1691. }
  1692. } func;
  1693. identical = selection->getSelectedTEValue(&func, offset_t, 0.001f);
  1694. identical = align_planar ? identical_planar_aligned : identical;
  1695. mPbrOffsetV->setValue(editable ? offset_t : 0.f);
  1696. mPbrOffsetV->setTentative(!identical);
  1697. }
  1698. mPbrOffsetV->setEnabled(editable && has_pbr_mat);
  1699. // Specular map rotation
  1700. if (has_pbr_mat)
  1701. {
  1702. struct pbr_rot_get final : public LLSelectedTEGetFunctor<F32>
  1703. {
  1704. F32 get(LLViewerObject* objectp, S32 face) override
  1705. {
  1706. F32 s = 1.f;
  1707. LLTextureEntry* tep = objectp->getTE(face);
  1708. LLGLTFMaterial* matp = tep ? tep->getGLTFMaterialOverride()
  1709. : NULL;
  1710. if (matp)
  1711. {
  1712. // *NOTE: here, we cheat and assume that all rotations
  1713. // are equal for all PBR texture maps. *TODO: see if it
  1714. // is a problem at all (probably not)... HB
  1715. s = matp->mTextureTransform[0].mRotation;
  1716. }
  1717. return s;
  1718. }
  1719. } func;
  1720. identical = selection->getSelectedTEValue(&func, rotation, 0.001f);
  1721. identical = align_planar ? identical_planar_aligned : identical;
  1722. mPbrRot->setValue(editable ? rotation * RAD_TO_DEG : 0.f);
  1723. mPbrRot->setTentative(!identical);
  1724. }
  1725. mPbrRot->setEnabled(editable && has_pbr_mat);
  1726. // Bump
  1727. mLabelBumpiness->setEnabled(editable);
  1728. U8 bump = 0;
  1729. {
  1730. struct bump_get final : public LLSelectedTEGetFunctor<U8>
  1731. {
  1732. U8 get(LLViewerObject* objectp, S32 face) override
  1733. {
  1734. LLTextureEntry* tep = objectp->getTE(face);
  1735. return tep ? tep->getBumpmap() : 0;
  1736. }
  1737. } func;
  1738. identical = selection->getSelectedTEValue(&func, bump);
  1739. }
  1740. if (normmap_id.notNull())
  1741. {
  1742. bump = BUMPY_TEXTURE;
  1743. }
  1744. LL_DEBUGS("Materials") << "Normal map texture: " << normmap_id
  1745. << " - Bumpininess index: " << (S32)bump
  1746. << LL_ENDL;
  1747. // Do not attempt to set the combo to BUMPY_TEXTURE if the "Use
  1748. // Texture" entry does not exist (in which case updateBumpyControls()
  1749. // will automatically create the entry and select it later for us).
  1750. if (bump != BUMPY_TEXTURE ||
  1751. mComboBumpiness->itemExists(mUseTextureText))
  1752. {
  1753. mComboBumpiness->setCurrentByIndex((S32)bump);
  1754. }
  1755. mComboBumpiness->setEnabled(editable);
  1756. mComboBumpiness->setTentative(!identical);
  1757. updateBumpyControls();
  1758. // Texgen
  1759. // Note: selected_texgen and identical_planar_texgen have been set far
  1760. // above, before texture offsets.
  1761. mLabelTexGen->setEnabled(editable);
  1762. mComboTexGen->setCurrentByIndex(selected_texgen >> TEM_TEX_GEN_SHIFT);
  1763. mComboTexGen->setEnabled(editable);
  1764. mComboTexGen->setTentative(!identical_planar_texgen);
  1765. if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)
  1766. {
  1767. mLabelTexScaleUnit->setText(mRepeatsPerMeterText);
  1768. }
  1769. else // if (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT)
  1770. {
  1771. mLabelTexScaleUnit->setText(mRepeatsPerFaceText);
  1772. }
  1773. // Full bright
  1774. U8 fullbright = 0;
  1775. {
  1776. struct fullbright_get final : public LLSelectedTEGetFunctor<U8>
  1777. {
  1778. U8 get(LLViewerObject* objectp, S32 face) override
  1779. {
  1780. LLTextureEntry* tep = objectp->getTE(face);
  1781. return tep ? tep->getFullbright() : 0;
  1782. }
  1783. } func;
  1784. identical = selection->getSelectedTEValue(&func, fullbright);
  1785. }
  1786. mCheckFullbright->setValue(fullbright != 0);
  1787. mCheckFullbright->setEnabled(editable);
  1788. mCheckFullbright->setTentative(!identical);
  1789. // Repeats per meter
  1790. F32 repeats = 1.f;
  1791. identical = false;
  1792. S32 map = mMapsRadio->getSelectedIndex();
  1793. switch (map)
  1794. {
  1795. case MATTYPE_SPECULAR:
  1796. {
  1797. struct shiny_repeats_get final
  1798. : public LLSelectedTEGetFunctor<F32>
  1799. {
  1800. F32 get(LLViewerObject* objectp, S32 face) override
  1801. {
  1802. LLTextureEntry* tep = objectp->getTE(face);
  1803. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1804. : NULL;
  1805. if (!matp)
  1806. {
  1807. return 1.f;
  1808. }
  1809. F32 repeats_s = 0.f;
  1810. F32 repeats_t = 0.f;
  1811. matp->getSpecularRepeat(repeats_s, repeats_t);
  1812. repeats_s /= objectp->getScale().mV[VX];
  1813. repeats_t /= objectp->getScale().mV[VY];
  1814. return llmax(repeats_s, repeats_t);
  1815. }
  1816. } func;
  1817. identical = selection->getSelectedTEValue(&func, repeats,
  1818. 0.001f);
  1819. enabled = shiny == SHINY_TEXTURE && specmap_id.notNull();
  1820. break;
  1821. }
  1822. case MATTYPE_NORMAL:
  1823. {
  1824. struct bump_repeats_get final
  1825. : public LLSelectedTEGetFunctor<F32>
  1826. {
  1827. F32 get(LLViewerObject* objectp, S32 face) override
  1828. {
  1829. LLTextureEntry* tep = objectp->getTE(face);
  1830. LLMaterial* matp = tep ? tep->getMaterialParams().get()
  1831. : NULL;
  1832. if (!matp)
  1833. {
  1834. return 1.f;
  1835. }
  1836. F32 repeats_s = 0.f;
  1837. F32 repeats_t = 0.f;
  1838. matp->getNormalRepeat(repeats_s, repeats_t);
  1839. repeats_s /= objectp->getScale().mV[VX];
  1840. repeats_t /= objectp->getScale().mV[VY];
  1841. return llmax(repeats_s, repeats_t);
  1842. }
  1843. } func;
  1844. identical = selection->getSelectedTEValue(&func, repeats,
  1845. 0.001f);
  1846. enabled = bump == BUMPY_TEXTURE && normmap_id.notNull();
  1847. break;
  1848. }
  1849. default: // MATTYPE_DIFFUSE *and* MATTYPE_PBR
  1850. {
  1851. struct tex_repeats_get final
  1852. : public LLSelectedTEGetFunctor<F32>
  1853. {
  1854. F32 get(LLViewerObject* objectp, S32 face) override
  1855. {
  1856. LLTextureEntry* tep = objectp->getTE(face);
  1857. if (!tep)
  1858. {
  1859. return 1.f;
  1860. }
  1861. U32 s_axis = VX;
  1862. U32 t_axis = VY;
  1863. // *BUG: only repeats along S axis and only works for
  1864. // boxes.
  1865. LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
  1866. #if 1
  1867. F32 repeats_s = tep->getScaleS() /
  1868. objectp->getScale().mV[s_axis];
  1869. F32 repeats_t = tep->getScaleT() /
  1870. objectp->getScale().mV[t_axis];
  1871. return llmax(repeats_s, repeats_t);
  1872. #else
  1873. return tep->getScaleS() /
  1874. objectp->getScale().mV[s_axis];
  1875. #endif
  1876. }
  1877. } func;
  1878. identical = selection->getSelectedTEValue(&func, repeats,
  1879. 0.001f);
  1880. enabled = id.notNull();
  1881. }
  1882. }
  1883. enabled = enabled && editable && !identical_planar_texgen;
  1884. mLabelRepeats->setEnabled(editable);
  1885. mRepeats->setValue(editable ? repeats : 1.f);
  1886. mRepeats->setTentative(!identical);
  1887. mRepeats->setEnabled(enabled);
  1888. mLabelRepeats->setEnabled(!identical_planar_texgen);
  1889. mRepeats->setEnabled(!identical_planar_texgen);
  1890. if (has_pbr_mat || mIsAlpha || normmap_id.notNull() ||
  1891. specmap_id.notNull())
  1892. {
  1893. mButtonResetMaterial->setEnabled(editable);
  1894. }
  1895. else
  1896. {
  1897. mButtonResetMaterial->setEnabled(false);
  1898. }
  1899. #if 0
  1900. mButtonAlignMap->setEnabled(selection->getObjectCount() > 1);
  1901. #endif
  1902. // Materials
  1903. {
  1904. struct mat_get final : public LLSelectedTEGetFunctor<LLMaterialPtr>
  1905. {
  1906. LLMaterialPtr get(LLViewerObject* objectp, S32 face) override
  1907. {
  1908. LLTextureEntry* tep = objectp->getTE(face);
  1909. return tep ? tep->getMaterialParams()
  1910. : LLMaterialPtr(NULL);
  1911. }
  1912. } func;
  1913. LLMaterialPtr material;
  1914. identical = selection->getSelectedTEValue(&func, material);
  1915. if (material && editable)
  1916. {
  1917. LL_DEBUGS("Materials") << "Material: " << material->asLLSD()
  1918. << LL_ENDL;
  1919. // There is duplicate code below, with what we already dealt
  1920. // with above... We should deal with material first *then* set
  1921. // the rest of the controls accordingly.
  1922. // *TODO: move this code up in getState() and properly merge
  1923. // with existing duplicate code.
  1924. // Alpha
  1925. alpha_mode = material->getDiffuseAlphaMode();
  1926. if (transparency > 0.f)
  1927. {
  1928. // It is invalid to have any alpha mode other than blend if
  1929. // transparency is greater than zero...
  1930. alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
  1931. }
  1932. if (!mIsAlpha)
  1933. {
  1934. // ... unless there is no alpha channel in the texture, in
  1935. // which case alpha mode MUST be none.
  1936. alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
  1937. }
  1938. mComboAlphaMode->setCurrentByIndex(alpha_mode);
  1939. mMaskCutoff->setValue(material->getAlphaMaskCutoff());
  1940. updateAlphaControls();
  1941. LLTextureEntry::e_texgen selected_texgen =
  1942. LLTextureEntry::TEX_GEN_DEFAULT;
  1943. bool identical_texgen = true;
  1944. bool identical_planar_texgen = false;
  1945. struct get_texgen final
  1946. : public LLSelectedTEGetFunctor<LLTextureEntry::e_texgen>
  1947. {
  1948. LLTextureEntry::e_texgen get(LLViewerObject* objectp,
  1949. S32 face) override
  1950. {
  1951. LLTextureEntry* tep = objectp->getTE(face);
  1952. return tep ? (LLTextureEntry::e_texgen)tep->getTexGen()
  1953. : LLTextureEntry::TEX_GEN_DEFAULT;
  1954. }
  1955. } func2;
  1956. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  1957. identical_texgen =
  1958. selection->getSelectedTEValue(&func2, selected_texgen);
  1959. identical_planar_texgen = identical_texgen &&
  1960. selected_texgen == LLTextureEntry::TEX_GEN_PLANAR;
  1961. // Shiny (specular)
  1962. F32 offset_x, offset_y, repeat_x, repeat_y, rot;
  1963. mSpecularCtrl->setImageAssetID(material->getSpecularID());
  1964. if (material->getSpecularID().notNull())
  1965. {
  1966. material->getSpecularRepeat(repeat_x, repeat_y);
  1967. if (identical_planar_texgen)
  1968. {
  1969. repeat_x *= 2.f;
  1970. repeat_y *= 2.f;
  1971. }
  1972. mShinyScaleU->setValue(fabsf(repeat_x));
  1973. mCheckShinyFlipS->setValue(LLSD(repeat_x < 0.f));
  1974. mShinyScaleV->setValue(fabsf(repeat_y));
  1975. mCheckShinyFlipT->setValue(LLSD(repeat_y < 0.f));
  1976. material->getSpecularOffset(offset_x, offset_y);
  1977. mShinyOffsetU->setValue(offset_x);
  1978. mShinyOffsetV->setValue(offset_y);
  1979. rot = material->getSpecularRotation();
  1980. mShinyRot->setValue(rot * RAD_TO_DEG);
  1981. mGlossiness->setValue(material->getSpecularLightExponent());
  1982. mEnvironment->setValue(material->getEnvironmentIntensity());
  1983. }
  1984. updateShinyControls();
  1985. if (material->getSpecularID().notNull())
  1986. {
  1987. mShinyColorSwatch->setOriginal(material->getSpecularLightColor());
  1988. mShinyColorSwatch->set(material->getSpecularLightColor(), true);
  1989. }
  1990. // Update the selection manager as to which channel we are
  1991. // editing so that it can reflect the correct overlay UI.
  1992. gSelectMgr.setTextureChannel(getTextureChannelToEdit());
  1993. // Bumpy (normal)
  1994. mNormalCtrl->setImageAssetID(material->getNormalID());
  1995. if (material->getNormalID().notNull())
  1996. {
  1997. material->getNormalRepeat(repeat_x, repeat_y);
  1998. if (identical_planar_texgen)
  1999. {
  2000. repeat_x *= 2.f;
  2001. repeat_y *= 2.f;
  2002. }
  2003. mBumpyScaleU->setValue(fabsf(repeat_x));
  2004. mCheckBumpyFlipS->setValue(LLSD(repeat_x < 0.f));
  2005. mBumpyScaleV->setValue(fabsf(repeat_y));
  2006. mCheckBumpyFlipT->setValue(LLSD(repeat_y < 0.f));
  2007. material->getNormalOffset(offset_x, offset_y);
  2008. mBumpyOffsetU->setValue(offset_x);
  2009. mBumpyOffsetV->setValue(offset_y);
  2010. rot = material->getNormalRotation();
  2011. mBumpyRot->setValue(rot * RAD_TO_DEG);
  2012. }
  2013. updateBumpyControls();
  2014. }
  2015. else
  2016. {
  2017. gSelectMgr.setTextureChannel(LLRender::DIFFUSE_MAP);
  2018. }
  2019. }
  2020. }
  2021. else
  2022. {
  2023. // Disable all UICtrls
  2024. clearCtrls();
  2025. // Disable non-UICtrls
  2026. mTextureCtrl->clear();
  2027. mTextureCtrl->setFallbackImageName("locked_image.j2c");
  2028. mTextureCtrl->setEnabled(false);
  2029. //mTextureCtrl->setValid(false);
  2030. mTextureCtrl->setBakeTextureEnabled(false);
  2031. mNormalCtrl->clear();
  2032. mNormalCtrl->setFallbackImageName("locked_image.j2c");
  2033. mNormalCtrl->setEnabled(false);
  2034. //mNormalCtrl->setValid(false);
  2035. mSpecularCtrl->clear();
  2036. mSpecularCtrl->setFallbackImageName("locked_image.j2c");
  2037. mSpecularCtrl->setEnabled(false);
  2038. //mSpecularCtrl->setValid(false);
  2039. mLabelDiffuseColor->setEnabled(false);
  2040. mColorSwatch->setEnabled(false);
  2041. mColorSwatch->setFallbackImageName("locked_image.j2c");
  2042. mColorSwatch->setValid(false);
  2043. mShinyColorSwatch->setEnabled(false);
  2044. mShinyColorSwatch->setFallbackImageName("locked_image.j2c");
  2045. mShinyColorSwatch->setValid(false);
  2046. mMatTexture = NULL;
  2047. mGLTFMaterial = NULL;
  2048. }
  2049. }
  2050. void LLPanelFace::sendTexture()
  2051. {
  2052. if (!mTextureCtrl->getTentative())
  2053. {
  2054. // We grab the item Id first, because we want to do a permissions check
  2055. // in the selection manager. ARGH!
  2056. LLUUID id = mTextureCtrl->getImageItemID();
  2057. if (id.isNull())
  2058. {
  2059. id = mTextureCtrl->getImageAssetID();
  2060. }
  2061. gSelectMgr.selectionSetTexture(id);
  2062. }
  2063. }
  2064. void LLPanelFace::sendBump()
  2065. {
  2066. S32 bumpiness = mComboBumpiness->getCurrentIndex();
  2067. if (bumpiness < BUMPY_TEXTURE)
  2068. {
  2069. mNormalCtrl->clear();
  2070. }
  2071. U8 bump = (U8)bumpiness & TEM_BUMP_MASK;
  2072. gSelectMgr.selectionSetBumpmap(bump);
  2073. }
  2074. void LLPanelFace::sendTexGen()
  2075. {
  2076. U8 tex_gen = (U8)mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT;
  2077. gSelectMgr.selectionSetTexGen(tex_gen);
  2078. }
  2079. void LLPanelFace::sendShiny()
  2080. {
  2081. S32 shininess = mComboShininess->getCurrentIndex();
  2082. if (shininess < SHINY_TEXTURE)
  2083. {
  2084. mSpecularCtrl->clear();
  2085. }
  2086. U8 shiny = (U8)shininess & TEM_SHINY_MASK;
  2087. gSelectMgr.selectionSetShiny(shiny);
  2088. }
  2089. void LLPanelFace::sendFullbright()
  2090. {
  2091. U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0;
  2092. gSelectMgr.selectionSetFullbright(fullbright);
  2093. }
  2094. void LLPanelFace::sendColor()
  2095. {
  2096. LLColor4 color = mColorSwatch->get();
  2097. gSelectMgr.selectionSetColorOnly(color);
  2098. }
  2099. void LLPanelFace::sendAlpha()
  2100. {
  2101. F32 alpha = (100.f - mTransparency->get()) / 100.f;
  2102. gSelectMgr.selectionSetAlphaOnly(alpha);
  2103. }
  2104. void LLPanelFace::sendGlow()
  2105. {
  2106. F32 glow = mGlow->get();
  2107. gSelectMgr.selectionSetGlow(glow);
  2108. }
  2109. void LLPanelFace::sendTextureInfo()
  2110. {
  2111. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  2112. if (mCheckPlanarAlign->getValue().asBoolean())
  2113. {
  2114. LLFace* last_face = getLastSelectedFace();
  2115. LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face);
  2116. selection->applyToTEs(&setfunc);
  2117. }
  2118. else
  2119. {
  2120. LLPanelFaceSetTEFunctor setfunc(this);
  2121. selection->applyToTEs(&setfunc);
  2122. }
  2123. LLPanelFaceSendFunctor sendfunc;
  2124. selection->applyToObjects(&sendfunc);
  2125. }
  2126. bool LLPanelFace::canEditSelection()
  2127. {
  2128. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  2129. LLViewerObject* objectp = selection->getFirstObject();
  2130. return objectp && objectp->getPCode() == LL_PCODE_VOLUME &&
  2131. objectp->permModify() && !objectp->isPermanentEnforced();
  2132. }
  2133. void LLPanelFace::updateAlphaControls()
  2134. {
  2135. bool enable = canEditSelection() && mIsAlpha &&
  2136. mTextureCtrl->getImageAssetID().notNull() &&
  2137. mTransparency->get() <= 0.f;
  2138. mLabelAlphaMode->setEnabled(enable);
  2139. mComboAlphaMode->setEnabled(enable);
  2140. S32 alpha_mode = mComboAlphaMode->getCurrentIndex();
  2141. enable = enable && alpha_mode == ALPHAMODE_MASK;
  2142. mLabelMaskCutoff->setEnabled(enable);
  2143. mMaskCutoff->setEnabled(enable);
  2144. // Set an equivalent cut-off value for non alpha masking mode:
  2145. switch (alpha_mode)
  2146. {
  2147. case ALPHAMODE_NONE:
  2148. case ALPHAMODE_BLEND:
  2149. mMaskCutoff->setValue(100);
  2150. break;
  2151. case ALPHAMODE_EMISSIVE:
  2152. mMaskCutoff->setValue(0);
  2153. break;
  2154. default:
  2155. break;
  2156. }
  2157. }
  2158. void LLPanelFace::updateShinyControls()
  2159. {
  2160. LLUUID shiny_tex_id = mSpecularCtrl->getImageAssetID();
  2161. S32 shiny = mComboShininess->getCurrentIndex();
  2162. LL_DEBUGS("Materials") << "Specular map texture: " << shiny_tex_id
  2163. << " - Shininess index: " << shiny << LL_ENDL;
  2164. // *HACK: This depends on adding the "Use texture" item at the end of a
  2165. // list of known length.
  2166. if (shiny_tex_id.notNull())
  2167. {
  2168. if (!mComboShininess->itemExists(mUseTextureText))
  2169. {
  2170. LL_DEBUGS("Materials") << "Adding a '" << mUseTextureText
  2171. << "' entry to the shininess combo."
  2172. << LL_ENDL;
  2173. mComboShininess->add(mUseTextureText);
  2174. mComboShininess->setCurrentByIndex(SHINY_TEXTURE);
  2175. // NORSPEC-94: Set default specular color to white
  2176. mShinyColorSwatch->setOriginal(LLColor4::white);
  2177. mShinyColorSwatch->set(LLColor4::white, true);
  2178. mGlossiness->setValue(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT);
  2179. mEnvironment->setValue(0);
  2180. }
  2181. }
  2182. else if (mComboShininess->itemExists(mUseTextureText))
  2183. {
  2184. LL_DEBUGS("Materials") << "Removing the '" << mUseTextureText
  2185. << "' entry from the shininess combo."
  2186. << LL_ENDL;
  2187. mComboShininess->remove(SHINY_TEXTURE);
  2188. if (shiny == SHINY_TEXTURE || shiny < 0)
  2189. {
  2190. mComboShininess->setCurrentByIndex(0);
  2191. }
  2192. }
  2193. LL_DEBUGS("Materials") << " New shininess index: "
  2194. << mComboShininess->getCurrentIndex() << LL_ENDL;
  2195. bool enable = canEditSelection() &&
  2196. mComboShininess->getCurrentIndex() == SHINY_TEXTURE;
  2197. mLabelGlossiness->setEnabled(enable);
  2198. mGlossiness->setEnabled(enable);
  2199. mLabelEnvironment->setEnabled(enable);
  2200. mEnvironment->setEnabled(enable);
  2201. mLabelShinyColor->setEnabled(enable);
  2202. mShinyColorSwatch->setEnabled(enable);
  2203. mShinyColorSwatch->setValid(enable);
  2204. }
  2205. void LLPanelFace::updateBumpyControls()
  2206. {
  2207. LLUUID bump_tex_id = mNormalCtrl->getImageAssetID();
  2208. S32 bump = mComboShininess->getCurrentIndex();
  2209. LL_DEBUGS("Materials") << "Normal map texture: " << bump_tex_id
  2210. << " - Bumpininess index: " << bump << LL_ENDL;
  2211. // *HACK: This depends on adding the "Use texture" item at the end of a
  2212. // list of known length.
  2213. if (bump_tex_id.notNull())
  2214. {
  2215. if (!mComboBumpiness->itemExists(mUseTextureText))
  2216. {
  2217. LL_DEBUGS("Materials") << "Adding a '" << mUseTextureText
  2218. << "' entry to the bumpininess combo."
  2219. << LL_ENDL;
  2220. mComboBumpiness->add(mUseTextureText);
  2221. mComboBumpiness->setCurrentByIndex(BUMPY_TEXTURE);
  2222. }
  2223. }
  2224. else if (mComboBumpiness->itemExists(mUseTextureText))
  2225. {
  2226. LL_DEBUGS("Materials") << "Removing the '" << mUseTextureText
  2227. << "' entry from the bumpininess combo."
  2228. << LL_ENDL;
  2229. mComboBumpiness->remove(BUMPY_TEXTURE);
  2230. if (bump == BUMPY_TEXTURE || bump < 0)
  2231. {
  2232. mComboBumpiness->setCurrentByIndex(0);
  2233. }
  2234. }
  2235. LL_DEBUGS("Materials") << " New bumpininess index: "
  2236. << mComboShininess->getCurrentIndex() << LL_ENDL;
  2237. }
  2238. void LLPanelFace::removeMaterial()
  2239. {
  2240. LL_DEBUGS("Materials") << "Resetting material entry" << LL_ENDL;
  2241. gSelectMgr.selectionRemoveMaterial();
  2242. // Check if any PBR material is present, and if yes, remove it. HB
  2243. struct pbr_mat_used final : public LLSelectedTEGetFunctor<bool>
  2244. {
  2245. bool get(LLViewerObject* objectp, S32 te) override
  2246. {
  2247. return objectp->getRenderMaterialID(te).notNull();
  2248. }
  2249. } func;
  2250. bool has_pbr_mat = false;
  2251. gSelectMgr.getSelection()->getSelectedTEValue(&func, has_pbr_mat);
  2252. if (has_pbr_mat)
  2253. {
  2254. gSelectMgr.selectionSetGLTFMaterial(LLUUID::null);
  2255. }
  2256. // Refresh the UI.
  2257. getState();
  2258. }
  2259. // Assign current state of UI to material definition for submit to sim
  2260. void LLPanelFace::updateMaterial()
  2261. {
  2262. S32 alpha_mode = mComboAlphaMode->getCurrentIndex();
  2263. S32 bumpiness = mComboBumpiness->getCurrentIndex();
  2264. S32 shininess = mComboShininess->getCurrentIndex();
  2265. LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
  2266. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  2267. struct gettexgen final
  2268. : public LLSelectedTEGetFunctor<LLTextureEntry::e_texgen>
  2269. {
  2270. LLTextureEntry::e_texgen get(LLViewerObject* object, S32 face) override
  2271. {
  2272. LLTextureEntry* te = object->getTE(face);
  2273. return te ? (LLTextureEntry::e_texgen)te->getTexGen()
  2274. : LLTextureEntry::TEX_GEN_DEFAULT;
  2275. }
  2276. } func;
  2277. bool identical = selection->getSelectedTEValue(&func, selected_texgen);
  2278. identical = identical && selected_texgen == LLTextureEntry::TEX_GEN_PLANAR;
  2279. bool default_blend =
  2280. mIsAlpha ? alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND
  2281. : alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
  2282. if (!default_blend || bumpiness == BUMPY_TEXTURE ||
  2283. shininess == SHINY_TEXTURE)
  2284. {
  2285. if (mComboAlphaMode->getTentative() && mNormalCtrl->getTentative() &&
  2286. mSpecularCtrl->getTentative())
  2287. {
  2288. // In these conditions, there is nothing to update !
  2289. return;
  2290. }
  2291. // The user's specified something that needs a material.
  2292. // This should match getState()
  2293. struct f1 final : public LLSelectedTEGetFunctor<LLMaterialPtr>
  2294. {
  2295. LLMaterialPtr get(LLViewerObject* object, S32 te_index) override
  2296. {
  2297. LLTextureEntry* te = object->getTE(te_index);
  2298. return te ? te->getMaterialParams() : LLMaterialPtr(NULL);
  2299. }
  2300. } func;
  2301. LLMaterialPtr curmatp;
  2302. selection->getSelectedTEValue(&func, curmatp);
  2303. bool new_mat = curmatp.isNull();
  2304. LLMaterialPtr matp;
  2305. if (new_mat)
  2306. {
  2307. matp = new LLMaterial();
  2308. }
  2309. else
  2310. {
  2311. matp = new LLMaterial(curmatp->asLLSD());
  2312. }
  2313. if (matp.isNull())
  2314. {
  2315. llwarns << "NULL material pointer, aborting !" << llendl;
  2316. llassert(false);
  2317. return;
  2318. }
  2319. if (!mComboAlphaMode->getTentative())
  2320. {
  2321. matp->setDiffuseAlphaMode(mComboAlphaMode->getCurrentIndex());
  2322. matp->setAlphaMaskCutoff((U8)mMaskCutoff->getValue().asInteger());
  2323. }
  2324. LLUUID norm_map_id = mNormalCtrl->getImageAssetID();
  2325. if (bumpiness == BUMPY_TEXTURE && norm_map_id.notNull() &&
  2326. !mNormalCtrl->getTentative())
  2327. {
  2328. LL_DEBUGS("Materials") << "Setting normal map texture, bumpiness = "
  2329. << bumpiness << LL_ENDL;
  2330. matp->setNormalID(norm_map_id);
  2331. matp->setNormalOffset(mBumpyOffsetU->getValue().asReal(),
  2332. mBumpyOffsetV->getValue().asReal());
  2333. F32 bumpy_scale_u = mBumpyScaleU->getValue().asReal();
  2334. if (mCheckBumpyFlipS->get())
  2335. {
  2336. bumpy_scale_u = -bumpy_scale_u;
  2337. }
  2338. F32 bumpy_scale_v = mBumpyScaleV->getValue().asReal();
  2339. if (mCheckBumpyFlipT->get())
  2340. {
  2341. bumpy_scale_v = -bumpy_scale_v;
  2342. }
  2343. if (identical)
  2344. {
  2345. bumpy_scale_u *= 0.5f;
  2346. bumpy_scale_v *= 0.5f;
  2347. }
  2348. matp->setNormalRepeat(bumpy_scale_u, bumpy_scale_v);
  2349. matp->setNormalRotation(mBumpyRot->getValue().asReal() *
  2350. DEG_TO_RAD);
  2351. }
  2352. else if (!mNormalCtrl->getTentative())
  2353. {
  2354. LL_DEBUGS("Materials") << "Removing normal map texture, bumpiness = "
  2355. << bumpiness << LL_ENDL;
  2356. matp->setNormalID(LLUUID::null);
  2357. matp->setNormalOffset(0.f, 0.f);
  2358. matp->setNormalRepeat(1.f, 1.f);
  2359. matp->setNormalRotation(0.f);
  2360. }
  2361. LLUUID spec_map_id = mSpecularCtrl->getImageAssetID();
  2362. if (shininess == SHINY_TEXTURE && spec_map_id.notNull() &&
  2363. !mSpecularCtrl->getTentative())
  2364. {
  2365. LL_DEBUGS("Materials") << "Setting specular map texture, shininess = "
  2366. << shininess << LL_ENDL;
  2367. matp->setSpecularID(spec_map_id);
  2368. matp->setSpecularOffset(mShinyOffsetU->getValue().asReal(),
  2369. mShinyOffsetV->getValue().asReal());
  2370. F32 shiny_scale_u = mShinyScaleU->getValue().asReal();
  2371. if (mCheckShinyFlipS->get())
  2372. {
  2373. shiny_scale_u = -shiny_scale_u;
  2374. }
  2375. F32 shiny_scale_v = mShinyScaleV->getValue().asReal();
  2376. if (mCheckShinyFlipT->get())
  2377. {
  2378. shiny_scale_v = -shiny_scale_v;
  2379. }
  2380. if (identical)
  2381. {
  2382. shiny_scale_u *= 0.5f;
  2383. shiny_scale_v *= 0.5f;
  2384. }
  2385. matp->setSpecularRepeat(shiny_scale_u, shiny_scale_v);
  2386. matp->setSpecularRotation(mShinyRot->getValue().asReal() *
  2387. DEG_TO_RAD);
  2388. // Override shininess to 0.2f if this is a new material
  2389. if (!new_mat)
  2390. {
  2391. matp->setSpecularLightColor(mShinyColorSwatch->get());
  2392. matp->setSpecularLightExponent(mGlossiness->getValue().asInteger());
  2393. matp->setEnvironmentIntensity(mEnvironment->getValue().asInteger());
  2394. }
  2395. }
  2396. else if (!mSpecularCtrl->getTentative())
  2397. {
  2398. LL_DEBUGS("Materials") << "Removing specular map texture, shininess = "
  2399. << shininess << LL_ENDL;
  2400. matp->setSpecularID(LLUUID::null);
  2401. matp->setSpecularOffset(0.f, 0.f);
  2402. matp->setSpecularRepeat(1.f, 1.f);
  2403. matp->setSpecularRotation(0.f);
  2404. matp->setSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR);
  2405. matp->setSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT);
  2406. matp->setEnvironmentIntensity(0);
  2407. }
  2408. LL_DEBUGS("Materials") << "Updating material:\n" << matp->asLLSD()
  2409. << LL_ENDL;
  2410. gSelectMgr.selectionSetMaterials(matp);
  2411. }
  2412. else
  2413. {
  2414. // The user has specified settings that do not need a material.
  2415. removeMaterial();
  2416. }
  2417. }
  2418. LLMaterialPtr LLPanelFace::createDefaultMaterial(LLMaterialPtr curmat)
  2419. {
  2420. LLMaterialPtr newmatp;
  2421. if (curmat.isNull())
  2422. {
  2423. U8 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
  2424. if (mIsAlpha)
  2425. {
  2426. // Use blend mode for the alpha channel
  2427. alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
  2428. }
  2429. newmatp = new LLMaterial();
  2430. if (newmatp)
  2431. {
  2432. newmatp->setDiffuseAlphaMode(alpha_mode);
  2433. }
  2434. }
  2435. else
  2436. {
  2437. newmatp = new LLMaterial(curmat->asLLSD());
  2438. }
  2439. if (!newmatp)
  2440. {
  2441. llerrs << "Could not create a new material !" << llendl;
  2442. }
  2443. return newmatp;
  2444. }
  2445. // This callback controls the *visibility* of the UI elements specific to the
  2446. // diffuse, normal, specular and PBR maps. The elements enabling/disabling is
  2447. // done in getState(), based on the primitive parameters. HB
  2448. //static
  2449. void LLPanelFace::onSelectMapType(LLUICtrl* ctrl, void* userdata)
  2450. {
  2451. LLPanelFace* self = (LLPanelFace*)userdata;
  2452. if (!self) return;
  2453. S32 map = self->mMapsRadio->getSelectedIndex();
  2454. bool show_diffuse = map == MATTYPE_DIFFUSE;
  2455. if (!show_diffuse && self->mTextureCtrl->isPickerShown())
  2456. {
  2457. self->mTextureCtrl->closeFloater();
  2458. }
  2459. self->mTextureCtrl->setVisible(show_diffuse);
  2460. self->mLabelAlphaMode->setVisible(show_diffuse);
  2461. self->mComboAlphaMode->setVisible(show_diffuse);
  2462. self->mLabelMaskCutoff->setVisible(show_diffuse);
  2463. self->mMaskCutoff->setVisible(show_diffuse);
  2464. self->mTexScaleU->setVisible(show_diffuse);
  2465. self->mTexScaleV->setVisible(show_diffuse);
  2466. self->mCheckTexFlipS->setVisible(show_diffuse);
  2467. self->mCheckTexFlipT->setVisible(show_diffuse);
  2468. self->mTexOffsetU->setVisible(show_diffuse);
  2469. self->mTexOffsetV->setVisible(show_diffuse);
  2470. self->mTexRot->setVisible(show_diffuse);
  2471. bool show_normal = map == MATTYPE_NORMAL;
  2472. if (!show_normal && self->mNormalCtrl->isPickerShown())
  2473. {
  2474. self->mNormalCtrl->closeFloater();
  2475. }
  2476. self->mNormalCtrl->setVisible(show_normal);
  2477. self->mLabelBumpiness->setVisible(show_normal);
  2478. self->mComboBumpiness->setVisible(show_normal);
  2479. self->mBumpyScaleU->setVisible(show_normal);
  2480. self->mBumpyScaleV->setVisible(show_normal);
  2481. self->mCheckBumpyFlipS->setVisible(show_normal);
  2482. self->mCheckBumpyFlipT->setVisible(show_normal);
  2483. self->mBumpyOffsetU->setVisible(show_normal);
  2484. self->mBumpyOffsetV->setVisible(show_normal);
  2485. self->mBumpyRot->setVisible(show_normal);
  2486. bool show_specular = map == MATTYPE_SPECULAR;
  2487. if (!show_specular && self->mSpecularCtrl->isPickerShown())
  2488. {
  2489. self->mSpecularCtrl->closeFloater();
  2490. }
  2491. self->mSpecularCtrl->setVisible(show_specular);
  2492. self->mLabelShinyColor->setVisible(show_specular);
  2493. self->mShinyColorSwatch->setVisible(show_specular);
  2494. self->mLabelShininess->setVisible(show_specular);
  2495. self->mComboShininess->setVisible(show_specular);
  2496. self->mLabelGlossiness->setVisible(show_specular);
  2497. self->mGlossiness->setVisible(show_specular);
  2498. self->mLabelEnvironment->setVisible(show_specular);
  2499. self->mEnvironment->setVisible(show_specular);
  2500. self->mShinyScaleU->setVisible(show_specular);
  2501. self->mShinyScaleV->setVisible(show_specular);
  2502. self->mCheckShinyFlipS->setVisible(show_specular);
  2503. self->mCheckShinyFlipT->setVisible(show_specular);
  2504. self->mShinyOffsetU->setVisible(show_specular);
  2505. self->mShinyOffsetV->setVisible(show_specular);
  2506. self->mShinyRot->setVisible(show_specular);
  2507. bool show_pbr = map == MATTYPE_PBR;
  2508. self->mPbrThumbBorder->setVisible(show_pbr);
  2509. self->mLabelPbrPreview->setVisible(show_pbr);
  2510. self->mPbrScaleU->setVisible(show_pbr);
  2511. self->mPbrScaleV->setVisible(show_pbr);
  2512. self->mPbrOffsetU->setVisible(show_pbr);
  2513. self->mPbrOffsetV->setVisible(show_pbr);
  2514. self->mPbrRot->setVisible(show_pbr);
  2515. self->mButtonEditPBR->setVisible(show_pbr);
  2516. self->mButtonLocalPBR->setVisible(show_pbr);
  2517. self->mButtonLoadPBR->setVisible(show_pbr);
  2518. self->mButtonSavePBR->setVisible(show_pbr);
  2519. // Hide incompatible or unrelated controls. HB
  2520. self->mLabelDiffuseColor->setVisible(!show_pbr);
  2521. self->mColorSwatch->setVisible(!show_pbr);
  2522. self->mTransparency->setVisible(!show_pbr);
  2523. self->mLabelColorTransp->setVisible(!show_pbr);
  2524. self->mGlow->setVisible(!show_pbr);
  2525. self->mCheckFullbright->setVisible(!show_pbr);
  2526. self->mCheckPlanarAlign->setVisible(!show_pbr);
  2527. self->mLabelRepeats->setVisible(!show_pbr);
  2528. self->mRepeats->setVisible(!show_pbr);
  2529. // Update all controls
  2530. self->getState();
  2531. }
  2532. //static
  2533. F32 LLPanelFace::valueGlow(LLViewerObject* objectp, S32 face)
  2534. {
  2535. if (objectp && objectp->getTE(face))
  2536. {
  2537. return (F32)objectp->getTE(face)->getGlow();
  2538. }
  2539. return 0.f;
  2540. }
  2541. //static
  2542. void LLPanelFace::onClickEditPBR(void*)
  2543. {
  2544. LLPreviewMaterial::loadLive();
  2545. }
  2546. //static
  2547. void LLPanelFace::onSelectLocalPBR(const LLUUID& id, void*)
  2548. {
  2549. if (id.notNull())
  2550. {
  2551. gSelectMgr.selectionSetGLTFMaterial(id);
  2552. }
  2553. }
  2554. //static
  2555. void LLPanelFace::onClickLocalPBR(void* userdata)
  2556. {
  2557. new HBFloaterLocalMaterial((LLView*)userdata, onSelectLocalPBR, NULL);
  2558. }
  2559. //static
  2560. void LLPanelFace::onSelectInventoryPBR(const std::vector<std::string>&,
  2561. const uuid_vec_t& ids, void*, bool)
  2562. {
  2563. if (!ids.empty())
  2564. {
  2565. gSelectMgr.selectionSetGLTFMaterial(ids[0]);
  2566. }
  2567. }
  2568. //static
  2569. void LLPanelFace::onClickLoadPBR(void* userdata)
  2570. {
  2571. HBFloaterInvItemsPicker* pickerp =
  2572. new HBFloaterInvItemsPicker((LLView*)userdata, onSelectInventoryPBR,
  2573. NULL);
  2574. pickerp->setAssetType(LLAssetType::AT_MATERIAL);
  2575. pickerp->setApplyImmediatelyControl("ApplyMaterialImmediately");
  2576. }
  2577. //static
  2578. void LLPanelFace::onClickSavePBR(void*)
  2579. {
  2580. LLPreviewMaterial::saveObjectsMaterial();
  2581. }
  2582. //static
  2583. void LLPanelFace::onClickRemoveMaterial(void* userdata)
  2584. {
  2585. LLPanelFace* self = (LLPanelFace*)userdata;
  2586. if (self)
  2587. {
  2588. self->removeMaterial();
  2589. }
  2590. }
  2591. //static
  2592. void LLPanelFace::onCommitColor(LLUICtrl* ctrl, void* userdata)
  2593. {
  2594. LLPanelFace* self = (LLPanelFace*)userdata;
  2595. if (self)
  2596. {
  2597. self->sendColor();
  2598. }
  2599. }
  2600. //static
  2601. void LLPanelFace::onCommitShinyColor(LLUICtrl* ctrl, void* userdata)
  2602. {
  2603. LLPanelFace* self = (LLPanelFace*)userdata;
  2604. if (self)
  2605. {
  2606. self->updateMaterial();
  2607. }
  2608. }
  2609. //static
  2610. void LLPanelFace::onCommitAlpha(LLUICtrl* ctrl, void* userdata)
  2611. {
  2612. LLPanelFace* self = (LLPanelFace*)userdata;
  2613. if (self)
  2614. {
  2615. self->mComboAlphaMode->setTentative(false);
  2616. self->sendAlpha();
  2617. }
  2618. }
  2619. //static
  2620. void LLPanelFace::onCancelColor(LLUICtrl* ctrl, void* userdata)
  2621. {
  2622. gSelectMgr.selectionRevertColors();
  2623. }
  2624. //static
  2625. void LLPanelFace::onSelectColor(LLUICtrl* ctrl, void* userdata)
  2626. {
  2627. LLPanelFace* self = (LLPanelFace*)userdata;
  2628. if (self)
  2629. {
  2630. gSelectMgr.saveSelectedObjectColors();
  2631. self->sendColor();
  2632. }
  2633. }
  2634. //static
  2635. void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata)
  2636. {
  2637. LLPanelFace* self = (LLPanelFace*)userdata;
  2638. if (self)
  2639. {
  2640. self->sendTexGen();
  2641. }
  2642. }
  2643. //static
  2644. void LLPanelFace::onCommitFullbright(LLUICtrl* ctrl, void* userdata)
  2645. {
  2646. LLPanelFace* self = (LLPanelFace*)userdata;
  2647. if (self)
  2648. {
  2649. self->sendFullbright();
  2650. }
  2651. }
  2652. //static
  2653. void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
  2654. {
  2655. LLPanelFace* self = (LLPanelFace*)userdata;
  2656. if (self)
  2657. {
  2658. self->sendGlow();
  2659. }
  2660. }
  2661. //static
  2662. void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata)
  2663. {
  2664. LLPanelFace* self = (LLPanelFace*)userdata;
  2665. if (self)
  2666. {
  2667. self->mComboAlphaMode->setTentative(false);
  2668. self->updateAlphaControls();
  2669. self->updateMaterial();
  2670. }
  2671. }
  2672. //static
  2673. void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
  2674. {
  2675. LLPanelFace* self = (LLPanelFace*)userdata;
  2676. if (self)
  2677. {
  2678. self->mNormalCtrl->setTentative(false);
  2679. self->sendBump();
  2680. self->updateBumpyControls();
  2681. self->updateMaterial();
  2682. }
  2683. }
  2684. //static
  2685. void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata)
  2686. {
  2687. LLPanelFace* self = (LLPanelFace*)userdata;
  2688. if (self)
  2689. {
  2690. self->mSpecularCtrl->setTentative(false);
  2691. self->sendShiny();
  2692. self->updateShinyControls();
  2693. self->updateMaterial();
  2694. }
  2695. }
  2696. //static
  2697. bool LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item, void*)
  2698. {
  2699. if (!item) return false;
  2700. for (LLObjectSelection::root_iterator
  2701. iter = gSelectMgr.getSelection()->root_begin(),
  2702. end = gSelectMgr.getSelection()->root_end();
  2703. iter != end; ++iter)
  2704. {
  2705. LLSelectNode* node = *iter;
  2706. LLViewerObject* obj = node->getObject();
  2707. if (!obj || !LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
  2708. {
  2709. return false;
  2710. }
  2711. }
  2712. return true;
  2713. }
  2714. //static
  2715. void LLPanelFace::onCommitTexture(LLUICtrl* ctrl, void* userdata)
  2716. {
  2717. LLPanelFace* self = (LLPanelFace*)userdata;
  2718. if (self)
  2719. {
  2720. gViewerStats.incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT);
  2721. self->sendTexture();
  2722. }
  2723. }
  2724. //static
  2725. void LLPanelFace::onCancelTexture(LLUICtrl* ctrl, void* userdata)
  2726. {
  2727. gSelectMgr.selectionRevertTextures();
  2728. }
  2729. //static
  2730. void LLPanelFace::onCommitNormalMap(LLUICtrl* ctrl, void* userdata)
  2731. {
  2732. LLPanelFace* self = (LLPanelFace*)userdata;
  2733. if (self)
  2734. {
  2735. self->mNormalCtrl->setTentative(false);
  2736. self->updateBumpyControls();
  2737. self->updateMaterial();
  2738. }
  2739. }
  2740. //static
  2741. void LLPanelFace::onCommitSpecularMap(LLUICtrl* ctrl, void* userdata)
  2742. {
  2743. LLPanelFace* self = (LLPanelFace*)userdata;
  2744. if (self)
  2745. {
  2746. self->mSpecularCtrl->setTentative(false);
  2747. self->updateShinyControls();
  2748. self->updateMaterial();
  2749. }
  2750. }
  2751. //static
  2752. void LLPanelFace::onSelectTexture(LLUICtrl* ctrl, void* userdata)
  2753. {
  2754. LLPanelFace* self = (LLPanelFace*)userdata;
  2755. if (self)
  2756. {
  2757. gSelectMgr.saveSelectedObjectTextures();
  2758. self->sendTexture();
  2759. }
  2760. }
  2761. //static
  2762. void LLPanelFace::onCommitTextureInfo(LLUICtrl* ctrl, void* userdata)
  2763. {
  2764. LLPanelFace* self = (LLPanelFace*)userdata;
  2765. if (self)
  2766. {
  2767. self->sendTextureInfo();
  2768. }
  2769. }
  2770. //static
  2771. void LLPanelFace::onCommitAlphaMaterial(LLUICtrl* ctrl, void* userdata)
  2772. {
  2773. LLPanelFace* self = (LLPanelFace*)userdata;
  2774. if (self)
  2775. {
  2776. self->mComboAlphaMode->setTentative(false);
  2777. self->updateMaterial();
  2778. }
  2779. }
  2780. //static
  2781. void LLPanelFace::onCommitBumpyMaterial(LLUICtrl* ctrl, void* userdata)
  2782. {
  2783. LLPanelFace* self = (LLPanelFace*)userdata;
  2784. if (self)
  2785. {
  2786. self->mNormalCtrl->setTentative(false);
  2787. self->updateMaterial();
  2788. }
  2789. }
  2790. //static
  2791. void LLPanelFace::onCommitShinyMaterial(LLUICtrl* ctrl, void* userdata)
  2792. {
  2793. LLPanelFace* self = (LLPanelFace*)userdata;
  2794. if (self)
  2795. {
  2796. self->mSpecularCtrl->setTentative(false);
  2797. self->updateMaterial();
  2798. }
  2799. }
  2800. //static
  2801. void LLPanelFace::onCommitPbrMaterial(LLUICtrl* ctrlp, void* userdata)
  2802. {
  2803. LLPanelFace* self = (LLPanelFace*)userdata;
  2804. if (!self || !ctrlp)
  2805. {
  2806. return;
  2807. }
  2808. enum
  2809. {
  2810. PBR_SCALE_U,
  2811. PBR_SCALE_V,
  2812. PBR_OFFSET_U,
  2813. PBR_OFFSET_V,
  2814. PBR_ROT,
  2815. };
  2816. S32 param = -1;
  2817. if (ctrlp == (LLUICtrl*)self->mPbrScaleU)
  2818. {
  2819. param = PBR_SCALE_U;
  2820. }
  2821. else if (ctrlp == (LLUICtrl*)self->mPbrScaleV)
  2822. {
  2823. param = PBR_SCALE_V;
  2824. }
  2825. else if (ctrlp == (LLUICtrl*)self->mPbrOffsetU)
  2826. {
  2827. param = PBR_OFFSET_U;
  2828. }
  2829. else if (ctrlp == (LLUICtrl*)self->mPbrOffsetV)
  2830. {
  2831. param = PBR_OFFSET_V;
  2832. }
  2833. else if (ctrlp == (LLUICtrl*)self->mPbrRot)
  2834. {
  2835. param = PBR_ROT;
  2836. }
  2837. else
  2838. {
  2839. llwarns << "Unknown control. Aborted." << llendl;
  2840. return;
  2841. }
  2842. F32 value = ctrlp->getValue().asReal();
  2843. U32 start = 0;
  2844. U32 end = LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT;
  2845. #if 0 // *TODO ?
  2846. if (!gSavedSettings.getBool("SyncMaterialSettings"))
  2847. {
  2848. start = self->mPbrTexChannel->getSelectedIndex();
  2849. end = start + 1;
  2850. }
  2851. #endif
  2852. struct LLSelectedTEGLTFMaterialFunctor : public LLSelectedTEFunctor
  2853. {
  2854. LLSelectedTEGLTFMaterialFunctor(S32 param, F32 value, U32 start,
  2855. U32 end)
  2856. : mParam(param),
  2857. mValue(value),
  2858. mStart(start),
  2859. mEnd(end)
  2860. {
  2861. }
  2862. bool apply(LLViewerObject* objectp, S32 face) override
  2863. {
  2864. const LLTextureEntry* tep = objectp->getTE(face);
  2865. if (!tep) return true;
  2866. LLGLTFMaterial new_mat;
  2867. if (tep->getGLTFMaterialOverride())
  2868. {
  2869. new_mat = *tep->getGLTFMaterialOverride();
  2870. }
  2871. for (U32 i = mStart; i < mEnd; ++i)
  2872. {
  2873. LLGLTFMaterial::TextureTransform& new_tt =
  2874. new_mat.mTextureTransform[i];
  2875. switch (mParam)
  2876. {
  2877. case PBR_SCALE_U:
  2878. new_tt.mScale.mV[VX] = mValue;
  2879. break;
  2880. case PBR_SCALE_V:
  2881. new_tt.mScale.mV[VY] = mValue;
  2882. break;
  2883. case PBR_OFFSET_U:
  2884. new_tt.mOffset.mV[VX] = mValue;
  2885. break;
  2886. case PBR_OFFSET_V:
  2887. new_tt.mOffset.mV[VY] = mValue;
  2888. break;
  2889. case PBR_ROT:
  2890. new_tt.mRotation = mValue;
  2891. default:
  2892. break;
  2893. }
  2894. }
  2895. LLGLTFMaterialList::queueModify(objectp, face, &new_mat);
  2896. return true;
  2897. }
  2898. S32 mParam;
  2899. F32 mValue;
  2900. U32 mStart;
  2901. U32 mEnd;
  2902. } select_func(param, value, start, end);
  2903. gSelectMgr.getSelection()->applyToTEs(&select_func);
  2904. }
  2905. // Commit the number of repeats per meter
  2906. //static
  2907. void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
  2908. {
  2909. LLPanelFace* self = (LLPanelFace*)userdata;
  2910. if (!self) return;
  2911. F32 repeats_per_meter = self->mRepeats->getValue().asReal();
  2912. S32 map = self->mMapsRadio->getSelectedIndex();
  2913. if (map == MATTYPE_DIFFUSE)
  2914. {
  2915. gSelectMgr.selectionTexScaleAutofit(repeats_per_meter);
  2916. return;
  2917. }
  2918. struct f_objscale_s final : public LLSelectedTEGetFunctor<F32>
  2919. {
  2920. F32 get(LLViewerObject* object, S32 face) override
  2921. {
  2922. U32 s_axis = VX;
  2923. U32 t_axis = VY;
  2924. LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
  2925. return object->getScale().mV[s_axis];
  2926. }
  2927. } scale_s_func;
  2928. struct f_objscale_t final : public LLSelectedTEGetFunctor<F32>
  2929. {
  2930. F32 get(LLViewerObject* object, S32 face) override
  2931. {
  2932. U32 s_axis = VX;
  2933. U32 t_axis = VY;
  2934. LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
  2935. return object->getScale().mV[t_axis];
  2936. }
  2937. } scale_t_func;
  2938. F32 obj_scale_s, obj_scale_t;
  2939. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  2940. selection->getSelectedTEValue(&scale_s_func, obj_scale_s, 0.001f);
  2941. selection->getSelectedTEValue(&scale_t_func, obj_scale_t, 0.001f);
  2942. F32 scale_u = obj_scale_s * repeats_per_meter;
  2943. F32 scale_v = obj_scale_t * repeats_per_meter;
  2944. if (map == MATTYPE_NORMAL)
  2945. {
  2946. self->mBumpyScaleU->setValue(fabsf(scale_u));
  2947. self->mCheckBumpyFlipS->setValue(LLSD(scale_u < 0.f));
  2948. self->mBumpyScaleV->setValue(fabsf(scale_v));
  2949. self->mCheckBumpyFlipT->setValue(LLSD(scale_v < 0.f));
  2950. }
  2951. else if (map == MATTYPE_SPECULAR)
  2952. {
  2953. self->mShinyScaleU->setValue(fabsf(scale_u));
  2954. self->mCheckShinyFlipS->setValue(LLSD(scale_u < 0.f));
  2955. self->mShinyScaleV->setValue(fabsf(scale_v));
  2956. self->mCheckShinyFlipT->setValue(LLSD(scale_v < 0.f));
  2957. }
  2958. self->updateMaterial();
  2959. }
  2960. //static
  2961. LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
  2962. {
  2963. if (!sInstance || !LLFloaterTools::isVisible())
  2964. {
  2965. return gSelectMgr.getTextureChannel();
  2966. }
  2967. S32 map = sInstance->mMapsRadio->getSelectedIndex();
  2968. switch (map)
  2969. {
  2970. case MATTYPE_NORMAL:
  2971. return LLRender::NORMAL_MAP;
  2972. case MATTYPE_SPECULAR:
  2973. return LLRender::SPECULAR_MAP;
  2974. default: // MATTYPE_DIFFUSE *and* MATTYPE_PBR
  2975. return LLRender::DIFFUSE_MAP;
  2976. }
  2977. }
  2978. // Commit the fit media texture to prim button
  2979. struct LLPanelFaceSetMediaFunctor final : public LLSelectedTEFunctor
  2980. {
  2981. bool apply(LLViewerObject* object, S32 te) override
  2982. {
  2983. LLTextureEntry* tep = object->getTE(te);
  2984. if (!tep) return true;
  2985. // *TODO: the media impl pointer should actually be stored by the
  2986. // texture
  2987. viewer_media_t impl =
  2988. LLViewerMedia::getMediaImplFromTextureID(tep->getID());
  2989. // Only do this if it's a media texture
  2990. if (impl.notNull())
  2991. {
  2992. LLPluginClassMedia* media = impl->getMediaPlugin();
  2993. if (media)
  2994. {
  2995. S32 media_width = media->getWidth();
  2996. S32 media_height = media->getHeight();
  2997. S32 texture_width = media->getTextureWidth();
  2998. S32 texture_height = media->getTextureHeight();
  2999. F32 scale_s = (F32)media_width / (F32)texture_width;
  3000. F32 scale_t = (F32)media_height / (F32)texture_height;
  3001. // Set scale and adjust offset
  3002. object->setTEScaleS(te, scale_s);
  3003. // Do not need to flip Y anymore since CEF does this for us now
  3004. object->setTEScaleT(te, scale_t);
  3005. object->setTEOffsetS(te, (scale_s - 1.f) * 0.5f);
  3006. object->setTEOffsetT(te, (scale_t - 1.f) * 0.5f);
  3007. }
  3008. }
  3009. return true;
  3010. };
  3011. };
  3012. //static
  3013. void LLPanelFace::onClickAutoFix(void*)
  3014. {
  3015. LLPanelFaceSetMediaFunctor setfunc;
  3016. gSelectMgr.getSelection()->applyToTEs(&setfunc);
  3017. LLPanelFaceSendFunctor sendfunc;
  3018. gSelectMgr.getSelection()->applyToObjects(&sendfunc);
  3019. }
  3020. #if 0
  3021. //static
  3022. void LLPanelFace::onAlignTextureLayers(void* userdata)
  3023. {
  3024. LLPanelFace* self = (LLPanelFace*)userdata;
  3025. if (!self)
  3026. {
  3027. return;
  3028. }
  3029. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  3030. LLFace* last_face = self->getLastSelectedFace();
  3031. S32 map = self->mMapsRadio->getSelectedIndex();
  3032. LLPanelFaceSetAlignedTEFunctor setfunc(self, last_face, map);
  3033. selection->applyToTEs(&setfunc);
  3034. }
  3035. #endif
  3036. //static
  3037. void LLPanelFace::onCommitPlanarAlign(LLUICtrl*, void* userdata)
  3038. {
  3039. LLPanelFace* self = (LLPanelFace*)userdata;
  3040. if (self)
  3041. {
  3042. // Update all controls
  3043. self->getState();
  3044. self->sendTextureInfo();
  3045. }
  3046. }