diff options
Diffstat (limited to 'indra/newview/llpanelface.h')
-rwxr-xr-x[-rw-r--r--] | indra/newview/llpanelface.h | 438 |
1 files changed, 426 insertions, 12 deletions
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 42be9b257f..b684881225 100644..100755 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -29,6 +29,10 @@ #include "v4color.h" #include "llpanel.h" +#include "llmaterial.h" +#include "llmaterialmgr.h" +#include "lltextureentry.h" +#include "llselectmgr.h" class LLButton; class LLCheckBoxCtrl; @@ -42,6 +46,48 @@ class LLTextureCtrl; class LLUICtrl; class LLViewerObject; class LLFloater; +class LLMaterialID; + +// Represents an edit for use in replicating the op across one or more materials in the selection set. +// +// The apply function optionally performs the edit which it implements +// as a functor taking Data that calls member func MaterialFunc taking SetValueType +// on an instance of the LLMaterial class. +// +// boost who? +// +template< + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > +class LLMaterialEditFunctor +{ +public: + LLMaterialEditFunctor(const DataType& data) : _data(data) {} + virtual ~LLMaterialEditFunctor() {} + virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } + DataType _data; +}; + +template< + typename DataType, + DataType (LLMaterial::*MaterialGetFunc)() > +class LLMaterialGetFunctor +{ +public: + LLMaterialGetFunctor() {} + virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } +}; + +template< + typename DataType, + DataType (LLTextureEntry::*TEGetFunc)() > +class LLTEGetFunctor +{ +public: + LLTEGetFunctor() {} + virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } +}; class LLPanelFace : public LLPanel { @@ -54,6 +100,19 @@ public: void setMediaURL(const std::string& url); void setMediaType(const std::string& mime_type); + LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) + { + LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); + llassert_always(new_material); + + // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture + // + new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); + return new_material; + } + + LLRender::eTexIndex getTextureChannelToEdit(); + protected: void getState(); @@ -61,11 +120,11 @@ protected: void sendTextureInfo(); // applies and sends texture scale, offset, etc. void sendColor(); // applies and sends color void sendAlpha(); // applies and sends transparency - void sendBump(); // applies and sends bump map + void sendBump(U32 bumpiness); // applies and sends bump map void sendTexGen(); // applies and sends bump map - void sendShiny(); // applies and sends shininess + void sendShiny(U32 shininess); // applies and sends shininess void sendFullbright(); // applies and sends full bright - void sendGlow(); + void sendGlow(); void sendMedia(); // this function is to return TRUE if the drag should succeed. @@ -74,23 +133,378 @@ protected: void onCommitTexture(const LLSD& data); void onCancelTexture(const LLSD& data); void onSelectTexture(const LLSD& data); + void onCommitSpecularTexture(const LLSD& data); + void onCancelSpecularTexture(const LLSD& data); + void onSelectSpecularTexture(const LLSD& data); + void onCommitNormalTexture(const LLSD& data); + void onCancelNormalTexture(const LLSD& data); + void onSelectNormalTexture(const LLSD& data); void onCommitColor(const LLSD& data); + void onCommitShinyColor(const LLSD& data); void onCommitAlpha(const LLSD& data); void onCancelColor(const LLSD& data); void onSelectColor(const LLSD& data); - - static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata); - static void onCommitBump( LLUICtrl* ctrl, void* userdata); + + void onCloseTexturePicker(const LLSD& data); + + // Make UI reflect state of currently selected material (refresh) + // and UI mode (e.g. editing normal map v diffuse map) + // + void updateUI(); + + // Convenience func to determine if all faces in selection have + // identical planar texgen settings during edits + // + bool isIdenticalPlanarTexgen(); + + // Callback funcs for individual controls + // + static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata); + static void onCommitBump( LLUICtrl* ctrl, void* userdata); static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); - static void onCommitShiny( LLUICtrl* ctrl, void* userdata); + static void onCommitShiny( LLUICtrl* ctrl, void* userdata); + static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); - static void onCommitGlow( LLUICtrl* ctrl, void *userdata); - static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); - - static void onClickApply(void*); + static void onCommitGlow( LLUICtrl* ctrl, void *userdata); + static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); + static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); static void onClickAutoFix(void*); - static F32 valueGlow(LLViewerObject* object, S32 face); + static F32 valueGlow(LLViewerObject* object, S32 face); + + + +private: + + bool isAlpha() { return mIsAlpha; } + + // Convenience funcs to keep the visual flack to a minimum + // + LLUUID getCurrentNormalMap(); + LLUUID getCurrentSpecularMap(); + U32 getCurrentShininess(); + U32 getCurrentBumpiness(); + U8 getCurrentDiffuseAlphaMode(); + U8 getCurrentAlphaMaskCutoff(); + U8 getCurrentEnvIntensity(); + U8 getCurrentGlossiness(); + F32 getCurrentBumpyRot(); + F32 getCurrentBumpyScaleU(); + F32 getCurrentBumpyScaleV(); + F32 getCurrentBumpyOffsetU(); + F32 getCurrentBumpyOffsetV(); + F32 getCurrentShinyRot(); + F32 getCurrentShinyScaleU(); + F32 getCurrentShinyScaleV(); + F32 getCurrentShinyOffsetU(); + F32 getCurrentShinyOffsetV(); + + // Update visibility of controls to match current UI mode + // (e.g. materials vs media editing) + // + // Do NOT call updateUI from within this function. + // + void updateVisibility(); + + // Make material(s) reflect current state of UI (apply edit) + // + void updateMaterial(); + + // Hey look everyone, a type-safe alternative to copy and paste! :) + // + + // Update material parameters by applying 'edit_func' to selected TEs + // + template< + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > + static void edit(LLPanelFace* p, DataType data) + { + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); + struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor + { + LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp) : _panel(panel), _edit(editp) {} + virtual ~LLSelectedTEEditMaterial() {}; + virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) + { + if (_edit) + { + LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material); + llassert_always(new_material); + + // Determine correct alpha mode for current diffuse texture + // (i.e. does it have an alpha channel that makes alpha mode useful) + // + // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329) + // need to get per-face answer to this question for sane alpha mode retention on updates. + // + bool is_alpha_face = object->isImageAlphaBlended(face); + + // need to keep this original answer for valid comparisons in logic below + // + U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + U8 default_alpha_mode = original_default_alpha_mode; + + if (!current_material.isNull()) + { + default_alpha_mode = current_material->getDiffuseAlphaMode(); + } + + // Insure we don't inherit the default of blend by accident... + // this will be stomped by a legit request to change the alpha mode by the apply() below + // + new_material->setDiffuseAlphaMode(default_alpha_mode); + + // Do "It"! + // + _edit->apply(new_material); + + U32 new_alpha_mode = new_material->getDiffuseAlphaMode(); + LLUUID new_normal_map_id = new_material->getNormalID(); + LLUUID new_spec_map_id = new_material->getSpecularID(); + + if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face) + { + new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + } + + bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode); + bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); + + if (!is_need_material) + { + LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; + LLMaterialMgr::getInstance()->remove(object->getID(),face); + new_material = NULL; + } + else + { + LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; + LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); + } + + object->setTEMaterialParams(face, new_material); + return new_material; + } + return NULL; + } + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit; + LLPanelFace* _panel; + } editor(p, &edit); + LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor); + } + + template< + typename DataType, + typename ReturnType, + ReturnType (LLMaterial::* const MaterialGetFunc)() const > + static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value) + { + DataType data_value; + struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType> + { + GetTEMaterialVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEMaterialVal() {} + + DataType get(LLViewerObject* object, S32 face) + { + DataType ret = _default; + LLMaterialPtr material_ptr; + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + if (tep) + { + material_ptr = tep->getMaterialParams(); + if (!material_ptr.isNull()) + { + ret = (material_ptr->*(MaterialGetFunc))(); + } + } + return ret; + } + DataType _default; + } GetFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value); + data_to_return = data_value; + } + + template< + typename DataType, + typename ReturnType, // some kids just have to different... + ReturnType (LLTextureEntry::* const TEGetFunc)() const > + static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value) + { + DataType data_value; + struct GetTEVal : public LLSelectedTEGetFunctor<DataType> + { + GetTEVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEVal() {} + + DataType get(LLViewerObject* object, S32 face) { + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + return tep ? ((tep->*(TEGetFunc))()) : _default; + } + DataType _default; + } GetTEValFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value ); + data_to_return = data_value; + } + + // Update vis and enabling of specific subsets of controls based on material params + // (e.g. hide the spec controls if no spec texture is applied) + // + void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateAlphaControls(); + + /* + * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. + * If agent selects texture which is not allowed to be applied for the currently selected object, + * all controls of the floater texture picker which allow to apply the texture will be disabled. + */ + void onTextureSelectionChanged(LLInventoryItem* itemp); + + bool mIsAlpha; + + /* These variables interlock processing of materials updates sent to + * the sim. mUpdateInFlight is set to flag that an update has been + * sent to the sim and not acknowledged yet, and cleared when an + * update is received from the sim. mUpdatePending is set when + * there's an update in flight and another UI change has been made + * that needs to be sent as a materials update, and cleared when the + * update is sent. This prevents the sim from getting spammed with + * update messages when, for example, the user holds down the + * up-arrow on a spinner, and avoids running afoul of its throttle. + */ + bool mUpdateInFlight; + bool mUpdatePending; + + #if defined(DEF_GET_MAT_STATE) + #undef DEF_GET_MAT_STATE + #endif + + #if defined(DEF_GET_TE_STATE) + #undef DEF_GET_TE_STATE + #endif + + #if defined(DEF_EDIT_MAT_STATE) + DEF_EDIT_MAT_STATE + #endif + + // Accessors for selected TE material state + // + #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue) \ + static void MaterialMemberFunc(DataType& data, bool& identical) \ + { \ + getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical,DefaultValue); \ + } + + // Mutators for selected TE material + // + #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc) \ + static void MaterialMemberFunc(LLPanelFace* p,DataType data) \ + { \ + edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p,data); \ + } + + // Accessors for selected TE state proper (legacy settings etc) + // + #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue) \ + static void TexEntryMemberFunc(DataType& data, bool& identical) \ + { \ + getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical,DefaultValue); \ + } + + class LLSelectedTEMaterial + { + public: + static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); + static void getMaxSpecularRepeats(F32& repeats, bool& identical); + static void getMaxNormalRepeats(F32& repeats, bool& identical); + static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); + + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null) + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f) + + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f) + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f) + DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f) + + DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); + DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); + + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); + + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); + + DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); + DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); + + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); + DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); + }; + + class LLSelectedTE + { + public: + + static void getFace(LLFace*& face_to_return, bool& identical_face); + static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); + static void getTexId(LLUUID& id, bool& identical); + static void getObjectScaleS(F32& scale_s, bool& identical); + static void getObjectScaleT(F32& scale_t, bool& identical); + static void getMaxDiffuseRepeats(F32& repeats, bool& identical); + + DEF_GET_TE_STATE(U8,U8,getBumpmap,0) + DEF_GET_TE_STATE(U8,U8,getShiny,0) + DEF_GET_TE_STATE(U8,U8,getFullbright,0) + DEF_GET_TE_STATE(F32,F32,getRotation,0.0f) + DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f) + DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f) + DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f) + DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f) + DEF_GET_TE_STATE(F32,F32,getGlow,0.0f) + DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT) + DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white) + }; }; #endif + |