diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/lldrawpoolwlsky.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/llfilepicker.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/lllocalgltfmaterials.cpp | 44 | ||||
| -rw-r--r-- | indra/newview/llmaterialeditor.cpp | 74 | ||||
| -rw-r--r-- | indra/newview/llmaterialeditor.h | 3 | ||||
| -rw-r--r-- | indra/newview/llpanelface.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.h | 2 | ||||
| -rw-r--r-- | indra/newview/lltinygltfhelper.cpp | 53 | ||||
| -rw-r--r-- | indra/newview/lltinygltfhelper.h | 4 | ||||
| -rw-r--r-- | indra/newview/llviewermenufile.cpp | 81 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_tools_texture.xml | 70 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/strings.xml | 5 | 
13 files changed, 251 insertions, 113 deletions
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 4bd7536964..f09d1abe2d 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -166,6 +166,11 @@ void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLoca  void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const  { +    if (!gSky.mVOSkyp) +    { +        return; +    } +      LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();  	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 1dd9a43b72..1ec25ccaa1 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -179,6 +179,7 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)  		SOUND_FILTER \  		IMAGE_FILTER \  		ANIM_FILTER \ +		MATERIAL_FILTER \  		L"\0";  		break;  	case FFLOAD_WAV: diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index 89f14c6cfa..a9099b1ce9 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -308,48 +308,10 @@ S32 LLLocalGLTFMaterialMgr::addUnit(const std::vector<std::string>& filenames)  S32 LLLocalGLTFMaterialMgr::addUnit(const std::string& filename)  { -    std::string exten = gDirUtilp->getExtension(filename); -    S32 materials_in_file = 0; - -    if (exten == "gltf" || exten == "glb") +    S32 materials_in_file = LLTinyGLTFHelper::getMaterialCountFromFile(filename); +    if (materials_in_file <= 0)      { -        tinygltf::TinyGLTF loader; -        std::string        error_msg; -        std::string        warn_msg; - -        tinygltf::Model model_in; - -        std::string filename_lc = filename; -        LLStringUtil::toLower(filename_lc); - -        // Load a tinygltf model fom a file. Assumes that the input filename has already been -        // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. -        bool decode_successful = false; -        if (std::string::npos == filename_lc.rfind(".gltf")) -        {  // file is binary -            decode_successful = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename_lc); -        } -        else -        {  // file is ascii -            decode_successful = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename_lc); -        } - -        if (!decode_successful) -        { -            LL_WARNS("GLTF") << "Cannot load, error: Failed to decode" << error_msg -                << ", warning:" << warn_msg -                << " file: " << filename -                << LL_ENDL; -            return 0; -        } - -        if (model_in.materials.empty()) -        { -            // materials are missing -            LL_WARNS("GLTF") << "Cannot load. File has no materials " << filename << LL_ENDL; -            return 0; -        } -        materials_in_file = model_in.materials.size(); +        return 0;      }      S32 loaded_materials = 0; diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 4b9d870d18..660ad879ca 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -390,10 +390,10 @@ BOOL LLMaterialEditor::postBuild()      if (!gAgent.isGodlike())      {          // Only allow fully permissive textures -        mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); -        mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); -        mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); -        mNormalTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); +        mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); +        mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); +        mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); +        mNormalTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);      }      // Texture callback @@ -1400,8 +1400,6 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std:              LLNotificationsUtil::add("MaterialCreated", params);          }); -        // todo: apply permissions from textures here if server doesn't -        // if any texture is 'no transfer', material should be 'no transfer' as well          const LLViewerRegion* region = gAgent.getRegion();          if (region)          { @@ -1684,6 +1682,59 @@ static void pack_textures(      }  } +void LLMaterialEditor::uploadMaterialFromFile(const std::string& filename, S32 index) +{ +    if (index < 0) +    { +        return; +    } + +    tinygltf::TinyGLTF loader; +    std::string        error_msg; +    std::string        warn_msg; + +    bool loaded = false; +    tinygltf::Model model_in; + +    std::string filename_lc = filename; +    LLStringUtil::toLower(filename_lc); + +    // Load a tinygltf model fom a file. Assumes that the input filename has already been +    // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. +    if (std::string::npos == filename_lc.rfind(".gltf")) +    {  // file is binary +        loaded = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename); +    } +    else +    {  // file is ascii +        loaded = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename); +    } + +    if (!loaded) +    { +        LLNotificationsUtil::add("CannotUploadMaterial"); +        return; +    } + +    if (model_in.materials.empty()) +    { +        // materials are missing +        return; +    } + +    if (index >= 0 && model_in.materials.size() <= index) +    { +        // material is missing +        return; +    } + +    // Todo: no point in loading whole editor +    LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD().with("filename", filename).with("index", LLSD::Integer(index))); +    me->loadMaterial(model_in, filename_lc, index, false); +    me->saveIfNeeded(); +} + +  void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index)  {      tinygltf::TinyGLTF loader; @@ -1976,7 +2027,7 @@ void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id)      me->setFocus(TRUE);  } -void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index) +void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index, bool open_floater)  {      if (model_in.materials.size() <= index)      { @@ -2074,10 +2125,13 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::      markChangesUnsaved(U32_MAX); -    openFloater(); -    setFocus(TRUE); +    if (open_floater) +    { +        openFloater(getKey()); +        setFocus(TRUE); -    applyToSelection(); +        applyToSelection(); +    }  }  bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures) diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 6deda5df50..d23a741e49 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -103,6 +103,7 @@ public:      void loadAsset() override;      // @index if -1 and file contains more than one material,      // will promt to select specific one +    static void uploadMaterialFromFile(const std::string& filename, S32 index);      static void loadMaterialFromFile(const std::string& filename, S32 index = -1);      void onSelectionChanged(); // live overrides selection changes @@ -242,7 +243,7 @@ private:      void setFromGLTFMaterial(LLGLTFMaterial* mat);      bool setFromSelection(); -    void loadMaterial(const tinygltf::Model &model, const std::string &filename_lc, S32 index); +    void loadMaterial(const tinygltf::Model &model, const std::string &filename_lc, S32 index, bool open_floater = true);      friend class LLMaterialFilePicker; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 3d72865f69..92e92ac6a6 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1064,7 +1064,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)  		F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;  		getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0); -		getChildView("ColorTrans")->setEnabled(editable); +		getChildView("ColorTrans")->setEnabled(editable && has_material);  		// Specular map  		LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec); @@ -1818,11 +1818,11 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,          LLUICtrl* gltfCtrlTextureOffsetU = getChild<LLUICtrl>("gltfTextureOffsetU");          LLUICtrl* gltfCtrlTextureOffsetV = getChild<LLUICtrl>("gltfTextureOffsetV"); -        gltfCtrlTextureScaleU->setEnabled(show_texture_info && has_pbr_capabilities); -        gltfCtrlTextureScaleV->setEnabled(show_texture_info && has_pbr_capabilities); -        gltfCtrlTextureRotation->setEnabled(show_texture_info && has_pbr_capabilities); -        gltfCtrlTextureOffsetU->setEnabled(show_texture_info && has_pbr_capabilities); -        gltfCtrlTextureOffsetV->setEnabled(show_texture_info && has_pbr_capabilities); +        gltfCtrlTextureScaleU->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material); +        gltfCtrlTextureScaleV->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material); +        gltfCtrlTextureRotation->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material); +        gltfCtrlTextureOffsetU->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material); +        gltfCtrlTextureOffsetV->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material);          // Control values are set in setMaterialOverridesFromSelection      } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 9891d7b078..6cf7e8850d 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1800,7 +1800,7 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,          allow_dnd = is_texture || is_mesh || is_material;      } -	if (getEnabled() && allow_dnd && allowDrop(item)) +	if (getEnabled() && allow_dnd && allowDrop(item, cargo_type, tooltip_msg))  	{  		if (drop)  		{ @@ -1952,7 +1952,7 @@ void LLTextureCtrl::draw()  	LLUICtrl::draw();  } -BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item) +BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg)  {  	BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());  	BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); @@ -1978,6 +1978,12 @@ BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item)  	}  	else  	{ +        PermissionMask mask = PERM_COPY | PERM_TRANSFER; +        if ((filter_perm_mask & mask) == mask +            && cargo_type == DAD_TEXTURE) +        { +            tooltip_msg.assign(LLTrans::getString("TooltipTextureRestrictedDrop")); +        }  		return FALSE;  	}  } diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 8d6a520dfd..d898722006 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -223,7 +223,7 @@ public:      EPickInventoryType getInventoryPickType() { return mInventoryPickType; };  private: -	BOOL allowDrop(LLInventoryItem* item); +	BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg);  	BOOL doDrop(LLInventoryItem* item);  private: diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index 05587af9bc..838524e910 100644 --- a/indra/newview/lltinygltfhelper.cpp +++ b/indra/newview/lltinygltfhelper.cpp @@ -182,12 +182,62 @@ LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tiny      return rawImage;  } +S32 LLTinyGLTFHelper::getMaterialCountFromFile(const std::string& filename) +{ +    std::string exten = gDirUtilp->getExtension(filename); +    S32 materials_in_file = 0; + +    if (exten == "gltf" || exten == "glb") +    { +        tinygltf::TinyGLTF loader; +        std::string        error_msg; +        std::string        warn_msg; + +        tinygltf::Model model_in; + +        std::string filename_lc = filename; +        LLStringUtil::toLower(filename_lc); + +        // Load a tinygltf model fom a file. Assumes that the input filename has already been +        // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. +        bool decode_successful = false; +        if (std::string::npos == filename_lc.rfind(".gltf")) +        {  // file is binary +            decode_successful = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename_lc); +        } +        else +        {  // file is ascii +            decode_successful = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename_lc); +        } + +        if (!decode_successful) +        { +            LL_WARNS("GLTF") << "Cannot load, error: Failed to decode" << error_msg +                << ", warning:" << warn_msg +                << " file: " << filename +                << LL_ENDL; +            return 0; +        } + +        if (model_in.materials.empty()) +        { +            // materials are missing +            LL_WARNS("GLTF") << "Cannot load. File has no materials " << filename << LL_ENDL; +            return 0; +        } +        materials_in_file = model_in.materials.size(); +    } +    return materials_in_file; +} +  bool LLTinyGLTFHelper::getMaterialFromFile(      const std::string& filename,      S32 mat_index, -    LLPointer < LLFetchedGLTFMaterial> material, +    LLFetchedGLTFMaterial* material,      std::string& material_name)  { +    llassert(material); +      tinygltf::TinyGLTF loader;      std::string        error_msg;      std::string        warn_msg; @@ -304,5 +354,4 @@ bool LLTinyGLTFHelper::getMaterialFromFile(      }      return true; -  } diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h index 250a4b0b9a..92c9876aff 100644 --- a/indra/newview/lltinygltfhelper.h +++ b/indra/newview/lltinygltfhelper.h @@ -43,10 +43,12 @@ namespace LLTinyGLTFHelper      LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index); +    S32 getMaterialCountFromFile(const std::string& filename); +      bool getMaterialFromFile(          const std::string& filename,          S32 mat_index, -        LLPointer < LLFetchedGLTFMaterial> material, +        LLFetchedGLTFMaterial* material,          std::string& material_name);      void initFetchedTextures(tinygltf::Material& material, diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index c028a663ea..33c7240fe0 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -38,6 +38,7 @@  #include "llfloatermap.h"  #include "llfloatermodelpreview.h"  #include "llmaterialeditor.h" +#include "llfloaterperms.h"  #include "llfloatersnapshot.h"  #include "llfloateroutfitsnapshot.h"  #include "llimage.h" @@ -49,9 +50,9 @@  #include "llinventorymodel.h"	// gInventory  #include "llpluginclassmedia.h"  #include "llresourcedata.h" -#include "lltoast.h" -#include "llfloaterperms.h"  #include "llstatusbar.h" +#include "lltinygltfhelper.h" +#include "lltoast.h"  #include "llviewercontrol.h"	// gSavedSettings  #include "llviewertexturelist.h"  #include "lluictrlfactory.h" @@ -471,19 +472,33 @@ void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification  		if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) &&  			LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost))  		{ -		LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( -			filename, -			asset_name, -			asset_name, 0, -			LLFolderType::FT_NONE, LLInventoryType::IT_NONE, -			LLFloaterPerms::getNextOwnerPerms("Uploads"), -			LLFloaterPerms::getGroupPerms("Uploads"), -			LLFloaterPerms::getEveryonePerms("Uploads"), -			expected_upload_cost)); +            LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( +                filename, +                asset_name, +                asset_name, 0, +                LLFolderType::FT_NONE, LLInventoryType::IT_NONE, +                LLFloaterPerms::getNextOwnerPerms("Uploads"), +                LLFloaterPerms::getGroupPerms("Uploads"), +                LLFloaterPerms::getEveryonePerms("Uploads"), +                expected_upload_cost)); + +            upload_new_resource(uploadInfo); +        } -		upload_new_resource(uploadInfo); -	} -} +        // gltf does not use normal upload procedure +        if (ext == "gltf" || ext == "glb") +        { +            S32 materials_in_file = LLTinyGLTFHelper::getMaterialCountFromFile(filename); + +            for (S32 i = 0; i < materials_in_file; i++) +            { +                // Todo: +                // 1. Decouple bulk upload from material editor +                // 2. Take into account possiblity of identical textures +                LLMaterialEditor::uploadMaterialFromFile(filename, i); +            } +        } +    }  }  bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S32& total_cost, S32& file_count, S32& bvh_count) @@ -511,6 +526,44 @@ bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S3  			total_cost += cost;  			file_count++;  		} + +        if (ext == "gltf" || ext == "glb") +        { +            S32 texture_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); +            S32 materials_in_file = LLTinyGLTFHelper::getMaterialCountFromFile(filename); + +            for (S32 i = 0; i < materials_in_file; i++) +            { +                LLPointer<LLFetchedGLTFMaterial> material = new LLFetchedGLTFMaterial(); +                std::string material_name; +                bool decode_successful = LLTinyGLTFHelper::getMaterialFromFile(filename, i, material.get(), material_name); + +                if (decode_successful) +                { +                    // Todo: make it account for possibility of same texture in different +                    // materials and even in scope of same material +                    S32 texture_count = 0; +                    if (material->mBaseColorId.notNull()) +                    { +                        texture_count++; +                    } +                    if (material->mMetallicRoughnessId.notNull()) +                    { +                        texture_count++; +                    } +                    if (material->mNormalId.notNull()) +                    { +                        texture_count++; +                    } +                    if (material->mEmissiveId.notNull()) +                    { +                        texture_count++; +                    } +                    total_cost += texture_count * texture_upload_cost; +                    file_count++; +                } +            } +        }  	}      return file_count > 0; diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index ba5a20dd22..3bcbe0ca3a 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -891,6 +891,40 @@               max_val="1"               name="shinyOffsetV"               width="265" /> +            <check_box +             follows="top|left" +             height="16" +             initial_value="false" +             label="Align planar faces" +             layout="topleft" +             left="7" +             name="checkbox planar align" +             tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping." +             top_delta="20" +             width="260" /> +			<button +             follows="left|top" +             layout="topleft" +			 left="9" +			 top="231" +			 height="20" +			 label="Align" +			 label_selected="Align current texture layers" +			 name="button align textures" +			 tool_tip="Align current texture layers" +			 width="66" /> +            <web_browser +             visible="false" +             enabled="false" +             border_visible="true" +             bottom_delta="0" +             follows="top|left" +             left="0" +             name="title_media" +             width="4" +             height="4" +             start_url="about:blank" +             decouple_texture_size="true" />              <!-- BEGIN PBR Material texture transform parameters -->              <spinner               follows="left|top" @@ -903,7 +937,7 @@               min_val="-100"               max_val="100"               name="gltfTextureScaleU" -             top_delta="-115" +             top_delta="34"               width="265" />              <spinner               follows="left|top" @@ -954,38 +988,4 @@               name="gltfTextureOffsetV"               width="265" />              <!-- END PBR Material texture transform parameters --> -            <check_box -             follows="top|left" -             height="16" -             initial_value="false" -             label="Align planar faces" -             layout="topleft" -             left="7" -             name="checkbox planar align" -             tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping." -             top_delta="43" -             width="260" /> -			<button -             follows="left|top" -             layout="topleft" -			 left="9" -			 top="231" -			 height="20" -			 label="Align" -			 label_selected="Align current texture layers" -			 name="button align textures" -			 tool_tip="Align current texture layers" -			 width="66" /> -            <web_browser -             visible="false" -             enabled="false" -             border_visible="true" -             bottom_delta="0" -             follows="top|left" -             left="0" -             name="title_media" -             width="4" -             height="4" -             start_url="about:blank" -             decouple_texture_size="true" />  </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e7e1a24f5e..255aff06be 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -319,6 +319,11 @@ Only items with unrestricted  'next owner' permissions  can be attached to notecards.  	</string> +	<string name="TooltipTextureRestrictedDrop"> +Only textures with unrestricted +copy and transfer permissions +are allowed. +	</string>  	<!-- searching - generic -->  	<string name="Searching">Searching...</string>  | 
