diff options
| author | Brad Linden <brad@lindenlab.com> | 2024-05-20 11:14:29 -0700 | 
|---|---|---|
| committer | Brad Linden <brad@lindenlab.com> | 2024-05-20 11:14:29 -0700 | 
| commit | 6af5db09faf5ea33a2d4c47b64e76f42edae178a (patch) | |
| tree | d746c96bab1bfd44c6373926608e91c0f2fd9e49 /indra/newview | |
| parent | eab232d3ed49bfb1f873e332ff57ec8c311c163b (diff) | |
| parent | 6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff) | |
Merge remote-tracking branch 'origin/DRTVWR-600-maint-A' into brad/merge-maint-a-to-dev
Diffstat (limited to 'indra/newview')
24 files changed, 198 insertions, 60 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c3f9a64fd6..4851efc9c4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11119,6 +11119,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>RenderAvatarFriendsOnly</key> +    <map> +        <key>Comment</key> +        <string>When enabled hides all avatars that aren't friends. Does not affect inworld control avatars (animeshes), nor self.</string> +        <key>Persist</key> +        <integer>0</integer> +        <key>Type</key> +        <string>Boolean</string> +        <key>Value</key> +        <real>0</real> +    </map>      <key>RenderAvatarComplexityMode</key>      <map>          <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl index 1a85d70256..6791fe44d9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl @@ -27,11 +27,11 @@  float random (vec2 uv)   { -    return 0; +    return 0.f;  }  float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness)  {      collectedColor = vec4(0); -    return 0; +    return 0.f;  } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5585d04c69..e0a334df01 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3000,7 +3000,7 @@ void LLAppViewer::initStrings()  {  	std::string strings_file = "strings.xml";  	std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file); -	if (strings_path_full.empty() || !gDirUtilp->fileExists(strings_path_full)) +	if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))  	{  		if (strings_path_full.empty())  		{ diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp index 16db32862d..29be2aaa6d 100644 --- a/indra/newview/llblocklist.cpp +++ b/indra/newview/llblocklist.cpp @@ -61,9 +61,8 @@ LLBlockList::LLBlockList(const Params& p)  	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(  									"menu_people_blocked_gear.xml",  									gMenuHolder, -									LLViewerMenuHolderGL::child_registry_t::instance(), -									true); -	if (context_menu) +									LLViewerMenuHolderGL::child_registry_t::instance()); +	if(context_menu)  	{  		mContextMenu = context_menu->getHandle();  	} diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 0c365d33c4..7d9fa2a475 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -131,7 +131,7 @@ public:  	static LLChatHistoryHeader* createInstance(const std::string& file_name)  	{  		LLChatHistoryHeader* pInstance = new LLChatHistoryHeader; -		pInstance->buildFromFile(file_name, true); +		pInstance->buildFromFile(file_name);	  		return pInstance;  	} @@ -587,7 +587,7 @@ public:  		mUserNameTextBox = getChild<LLTextBox>("user_name");  		mTimeBoxTextBox = getChild<LLTextBox>("time_box"); -		mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance(), true); +		mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance());          if (mInfoCtrl)          {              mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl)); @@ -1181,7 +1181,7 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p)  LLView* LLChatHistory::getSeparator()  { -	LLPanel* separator = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>(mMessageSeparatorFilename, NULL, LLPanel::child_registry_t::instance(), true); +	LLPanel* separator = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>(mMessageSeparatorFilename, NULL, LLPanel::child_registry_t::instance());  	return separator;  } diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 030d24bed8..bc61fac00b 100644 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -657,11 +657,12 @@ void LLControlGroupCLP::configure(const std::string& config_filename, LLControlG      // This method reads the llsd based config file, and uses it to set       // members of a control group.      LLSD clpConfigLLSD; +     +    llifstream input_stream; +    input_stream.open(config_filename.c_str(), std::ios::in | std::ios::binary); -    std::string xml = gDirUtilp->getFileContents(config_filename); -    if (!xml.empty()) +    if(input_stream.is_open())      { -        std::stringstream input_stream(xml);          LLSDSerialize::fromXML(clpConfigLLSD, input_stream);          for(LLSD::map_iterator option_itr = clpConfigLLSD.beginMap();               option_itr != clpConfigLLSD.endMap();  diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h index 7beefad191..fd1cda7a2c 100644 --- a/indra/newview/llcontrolavatar.h +++ b/indra/newview/llcontrolavatar.h @@ -85,6 +85,7 @@ public:      virtual bool shouldRenderRigged() const;  	virtual bool isImpostor();  +    virtual bool isBuddy() const { return false; }      bool mPlaying; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 32f0e185ce..a07827d395 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -370,6 +370,15 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  		return;  	} +    LLCachedControl<bool> debug_invisible(gSavedSettings, "RenderAvatarFriendsOnly", false); +    if (debug_invisible() +        && !avatarp->isControlAvatar() +        && !avatarp->isSelf() +        && !avatarp->isBuddy()) +    { +        return; +    } +      LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();  	bool impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();      // no shadows if the shadows are causing this avatar to breach the limit. @@ -723,6 +732,17 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} +    LLCachedControl<bool> friends_only(gSavedSettings, "RenderAvatarFriendsOnly", false); +    if (!single_avatar +        && friends_only() +        && !avatarp->isUIAvatar() +        && !avatarp->isControlAvatar() +        && !avatarp->isSelf() +        && !avatarp->isBuddy()) +    { +        return; +    } +  	bool impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor() && !single_avatar;  	if (( avatarp->isInMuteList()  diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index a46cc0ce30..727f5592cd 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -886,11 +886,10 @@ const LLButton::Params& LLFavoritesBarCtrl::getButtonParams()  	if (!params_initialized)  	{  		LLXMLNodePtr button_xml_node; -		static const std::string filename("favorites_bar_button.xml"); -		if (LLUICtrlFactory::getLayeredXMLNode(filename, button_xml_node, LLDir::CURRENT_SKIN, true)) +		if(LLUICtrlFactory::getLayeredXMLNode("favorites_bar_button.xml", button_xml_node))  		{  			LLXUIParser parser; -			parser.readXUI(button_xml_node, button_params, filename); +			parser.readXUI(button_xml_node, button_params, "favorites_bar_button.xml");  		}  		params_initialized = true;  	} diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 72fbab406b..5461f98624 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -633,7 +633,7 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type, bool cl  void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )  {  	std::string filename(gDirUtilp->add(subdir, filename_in)); -	std::string expanded_filename = gDirUtilp->findSkinnedFilename(LLDir::HTML, filename); +	std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", filename);  	if (expanded_filename.empty())  	{ diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index f6ec455ae1..c94f87bddc 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -68,6 +68,8 @@  #include "lltabcontainer.h"  #include "lltextbox.h" +#include <filesystem> +  #include <boost/algorithm/string.hpp>  bool LLModelPreview::sIgnoreLoadedCallback = false; @@ -1067,6 +1069,29 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)      { //only replace given LoD          mModel[loaded_lod] = mModelLoader->mModelList;          mScene[loaded_lod] = mModelLoader->mScene; + +        // Duplicate the model if it is an internal bounding box model +        if (loaded_lod == LLModel::LOD_PHYSICS && +            mBaseModel.size() > 1 && // This makes sense for multiple models only +            mModelLoader->mModelList.size() == 1 && // Just on the off-chance +            mModelLoader->mScene.size() == 1 &&     // Just on the off-chance +            std::filesystem::path(mModelLoader->mFilename).filename() == "cube.dae") +        { +            // Create a copy of the just loaded model for each model in mBaseModel +            const LLModel* origin = mModelLoader->mModelList.front(); +            const LLModelInstance& mi = mModelLoader->mScene.begin()->second.front(); +            for (U32 i = 1; i < mBaseModel.size(); ++i) +            { +                LLPointer<LLModel> copy(new LLModel(origin->getParams(), origin->getDetail())); +                copy->mLabel = origin->mLabel; +                copy->copyVolumeFaces(origin); +                copy->mPosition = origin->mPosition; +                copy->mMaterialList = origin->mMaterialList; +                mModel[loaded_lod].push_back(copy); +                mScene[loaded_lod][mi.mTransform].push_back(LLModelInstance(copy, copy->mLabel, mi.mTransform, mi.mMaterial)); +            } +        } +          mVertexBuffer[loaded_lod].clear();          setPreviewLOD(loaded_lod); @@ -1163,6 +1188,17 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)                                      LLFloaterModelPreview::addStringToLog(out, false);                                  }                                  mModel[loaded_lod][idx]->mLabel = name; +                                // Rename the correspondent instance as well +                                [&]() +                                { +                                    for (auto& p : mScene[loaded_lod]) +                                        for (auto& i : p.second) +                                            if (i.mModel == mModel[loaded_lod][idx]) +                                            { +                                                i.mLabel = name; +                                                return; +                                            } +                                }();                              }                          }                      } diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index 79a90c4f4c..75edac105a 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -594,7 +594,7 @@ LLSystemNotificationListItem::LLSystemNotificationListItem(const Params& p)      mSystemNotificationIcon(NULL),      mIsCaution(false)  { -    buildFromFile("panel_notification_list_item.xml", true); +    buildFromFile("panel_notification_list_item.xml");      mIsCaution = p.notification_priority >= NOTIFICATION_PRIORITY_HIGH;      if (mIsCaution)      { diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index a8553b654e..36605fed7a 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -260,10 +260,16 @@ bool LLPanelNearByMedia::handleRightMouseDown(S32 x, S32 y, MASK mask)      S32 x_list, y_list;      localPointToOtherView(x, y, &x_list, &y_list, mMediaList);      if (mMoreLessBtn->getToggleState() -        && mMediaList->pointInView(x_list, y_list) -        && mMediaList->selectItemAt(x_list, y_list, mask)) +        && mMediaList->pointInView(x_list, y_list))      { -        if (mContextMenu) +        LLScrollListItem* hit_item = mMediaList->hitItem(x_list, y_list); +        bool selected = hit_item && hit_item->getSelected(); +        if (!selected) +        { +            selected = mMediaList->selectItemAt(x_list, y_list, mask); +        } +         +        if (selected && mContextMenu)          {              mContextMenu->buildDrawLabels();              mContextMenu->updateParent(LLMenuGL::sMenuContainer); diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 28428112a1..91b8f0496e 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -67,6 +67,7 @@ const F32 PREVIEW_TEXTURE_MIN_ASPECT = 0.005f;  LLPreviewTexture::LLPreviewTexture(const LLSD& key)  	: LLPreview(key),  	  mLoadingFullImage( false ), +      mSavingMultiple(false),  	  mShowKeepDiscard(false),  	  mCopyToInv(false),  	  mIsCopyable(false), @@ -310,9 +311,12 @@ void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenam  	// remember the user-approved/edited file name.  	mSaveFileName = filenames[0]; +    mSavingMultiple = false;  	mLoadingFullImage = true;  	getWindow()->incBusyCount(); +    LL_DEBUGS("FileSaveAs") << "Scheduling saving file to " << mSaveFileName << LL_ENDL; +  	mImage->forceToSaveRawImage(0);//re-fetch the raw image if the old one is removed.  	mImage->setLoadedCallback(LLPreviewTexture::onFileLoadedForSave,  		0, true, false, new LLUUID(mItemUUID), &mCallbackTextureList); @@ -322,35 +326,16 @@ void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenam  void LLPreviewTexture::saveMultipleToFile(const std::string& file_name)  {      std::string texture_location(gSavedSettings.getString("TextureSaveLocation"));	 -    std::string texture_name = file_name.empty() ? getItem()->getName() : file_name; -     -    std::string filepath; -    S32 i = 0; -    S32 err = 0; -    std::string extension(".png"); -    do -    { -        filepath = texture_location; -        filepath += gDirUtilp->getDirDelimiter(); -        filepath += texture_name; - -        if (i != 0) -        { -            filepath += llformat("_%.3d", i); -        } +    std::string texture_name = LLDir::getScrubbedFileName(file_name.empty() ? getItem()->getName() : file_name); -        filepath += extension; +    mSaveFileName = texture_location + gDirUtilp->getDirDelimiter() + texture_name + ".png"; -        llstat stat_info; -        err = LLFile::stat( filepath, &stat_info ); -        i++; -    } while (-1 != err);  // Search until the file is not found (i.e., stat() gives an error). -     -     -    mSaveFileName = filepath; +    mSavingMultiple = true;      mLoadingFullImage = true;      getWindow()->incBusyCount(); +    LL_DEBUGS("FileSaveAs") << "Scheduling saving file to " << mSaveFileName << LL_ENDL; +      mImage->forceToSaveRawImage(0);//re-fetch the raw image if the old one is removed.      mImage->setLoadedCallback(LLPreviewTexture::onFileLoadedForSave,          0, true, false, new LLUUID(mItemUUID), &mCallbackTextureList); @@ -451,8 +436,39 @@ void LLPreviewTexture::onFileLoadedForSave(bool success,  	if( self && final && success )  	{ +        LL_DEBUGS("FileSaveAs") << "Saving file to " << self->mSaveFileName << LL_ENDL;  		const U32 ext_length = 3;  		std::string extension = self->mSaveFileName.substr( self->mSaveFileName.length() - ext_length); + +        std::string filepath; +        if (self->mSavingMultiple) +        { +            std::string part_path = self->mSaveFileName.substr(0, self->mSaveFileName.length() - ext_length - 1); + +            S32 i = 0; +            S32 err = 0; +            do +            { +                filepath = part_path; + +                if (i != 0) +                { +                    filepath += llformat("_%.3d", i); +                } + +                filepath += "."; +                filepath += extension; + +                llstat stat_info; +                err = LLFile::stat(filepath, &stat_info); +                i++; +            } while (-1 != err);  // Search until the file is not found (i.e., stat() gives an error). +        } +        else +        { +            filepath = self->mSaveFileName; +        } +  		LLStringUtil::toLower(extension);  		// We only support saving in PNG or TGA format  		LLPointer<LLImageFormatted> image; @@ -468,13 +484,13 @@ void LLPreviewTexture::onFileLoadedForSave(bool success,  		if( image && !image->encode( src, 0 ) )  		{  			LLSD args; -			args["FILE"] = self->mSaveFileName; +			args["FILE"] = filepath;  			LLNotificationsUtil::add("CannotEncodeFile", args);  		} -		else if( image && !image->save( self->mSaveFileName ) ) +		else if( image && !image->save(filepath) )  		{  			LLSD args; -			args["FILE"] = self->mSaveFileName; +			args["FILE"] = filepath;  			LLNotificationsUtil::add("CannotWriteFile", args);  		}  		else @@ -482,6 +498,7 @@ void LLPreviewTexture::onFileLoadedForSave(bool success,  			self->mSavedFileTimer.reset();  			self->mSavedFileTimer.setTimerExpirySec( SECONDS_TO_SHOW_FILE_SAVED_MSG );  		} +        LL_DEBUGS("FileSaveAs") << "Done saving file to " << filepath << LL_ENDL;  		self->mSaveFileName.clear();  	} diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index fdc6dddb38..e8a0a43245 100644 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -86,6 +86,7 @@ private:  	S32                 mImageOldBoostLevel;  	std::string			mSaveFileName;  	LLFrameTimer		mSavedFileTimer; +    bool				mSavingMultiple;  	bool				mLoadingFullImage;  	bool                mShowKeepDiscard;  	bool                mCopyToInv; diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 5cf2e89c63..f6fadf276c 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -119,7 +119,7 @@ LLToast::LLToast(const LLToast::Params& p)  {  	mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs)); -	buildFromFile("panel_toast.xml", true); +	buildFromFile("panel_toast.xml");  	setCanDrag(false); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index f7bebf08aa..1f6a88cd95 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -266,9 +266,9 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )  	LLRect current_rect = getRect();  	setXMLFilename(""); -	buildFromFile("panel_notification.xml", true); +	buildFromFile("panel_notification.xml"); -    if (rect != LLRect::null) +    if(rect != LLRect::null)      {          this->setShape(rect);      } diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp index 49fbf885eb..f6fc9e7889 100644 --- a/indra/newview/lltoastscriptquestion.cpp +++ b/indra/newview/lltoastscriptquestion.cpp @@ -37,7 +37,7 @@ LLToastScriptQuestion::LLToastScriptQuestion(const LLNotificationPtr& notificati  :  LLToastPanel(notification)  { -	buildFromFile("panel_script_question_toast.xml", true); +	buildFromFile("panel_script_question_toast.xml");  }  bool LLToastScriptQuestion::postBuild() diff --git a/indra/newview/lluiavatar.h b/indra/newview/lluiavatar.h index bcdffedef2..d9fe003155 100644 --- a/indra/newview/lluiavatar.h +++ b/indra/newview/lluiavatar.h @@ -39,6 +39,7 @@ public:      LLUIAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);  	virtual void 			initInstance(); // Called after construction to initialize the class.  	virtual	~LLUIAvatar(); +    virtual bool isBuddy() const { return false; }  };  #endif //LL_CONTROLAVATAR_H diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 67ce589142..9ed96a22d6 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -416,7 +416,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&  		return NULL ;  	} -	std::string full_path = gDirUtilp->findSkinnedFilename(LLDir::TEXTURES, filename); +	std::string full_path = gDirUtilp->findSkinnedFilename("textures", filename);  	if (full_path.empty())  	{  		LL_WARNS() << "Failed to find local image file: " << filename << LL_ENDL; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 873622d44e..d8712737ae 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -207,7 +207,7 @@ const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0;  const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024;  const F32 MAX_TEXTURE_WAIT_TIME_SEC = 60; -const F32 MAX_ATTACHMENT_WAIT_TIME_SEC = 120; +const F32 MAX_ATTACHMENT_WAIT_TIME_SEC = 60;  const S32 MIN_NONTUNED_AVS = 5; @@ -680,7 +680,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mMutedAVColor(LLColor4::white /* used for "uninitialize" */),  	mFirstFullyVisible(true),      mFirstDecloudTime(-1.f), -	mFirstUseDelaySeconds(FIRST_APPEARANCE_CLOUD_MIN_DELAY),  	mFullyLoaded(false),  	mPreviousFullyLoaded(false),  	mFullyLoadedInitialized(false), @@ -2587,6 +2586,27 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)  		LL_INFOS() << "Warning!  Idle on dead avatar" << LL_ENDL;  		return;  	} + +    LLCachedControl<bool> friends_only(gSavedSettings, "RenderAvatarFriendsOnly", false); +    if (friends_only() +        && !isUIAvatar() +        && !isControlAvatar() +        && !isSelf() +        && !isBuddy()) +    { +        if (mNameText) +        { +            mNameIsSet = false; +            mNameText->markDead(); +            mNameText = NULL; +            sNumVisibleChatBubbles--; +        } +        deleteParticleSource(); +        mVoiceVisualizer->setVoiceEnabled(false); + +        return; +    } +      // record time and refresh "tooSlow" status      updateTooSlow(); @@ -8287,7 +8307,7 @@ bool LLVOAvatar::updateIsFullyLoaded()                    );          // compare amount of attachments to one reported by simulator -        if (!loading && !isSelf() && rez_status < 4 && mLastCloudAttachmentCount != mSimAttachments.size()) +        if (!loading && !isSelf() && rez_status < 4 && mLastCloudAttachmentCount < mSimAttachments.size())          {              S32 attachment_count = getAttachmentCount();              if (mLastCloudAttachmentCount != attachment_count) @@ -8355,11 +8375,12 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading)  	if (mFirstFullyVisible)  	{ +        F32 first_use_delay = FIRST_APPEARANCE_CLOUD_MIN_DELAY;          if (!isSelf() && loading)          {                  // Note that textures can causes 60s delay on thier own                  // so this delay might end up on top of textures' delay -                mFirstUseDelaySeconds = llclamp( +                first_use_delay = llclamp(                      mFirstAppearanceMessageTimer.getElapsedTimeF32(),                      FIRST_APPEARANCE_CLOUD_MIN_DELAY,                      FIRST_APPEARANCE_CLOUD_MAX_DELAY); @@ -8368,10 +8389,10 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading)                  {                      // Impostors are less of a priority,                      // let them stay cloud longer -                    mFirstUseDelaySeconds *= FIRST_APPEARANCE_CLOUD_IMPOSTOR_MODIFIER; +                    first_use_delay *= FIRST_APPEARANCE_CLOUD_IMPOSTOR_MODIFIER;                  }          } -		mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > mFirstUseDelaySeconds); +		mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > first_use_delay);  	}  	else  	{ @@ -9382,7 +9403,17 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe              << (attachment_id.isNull() ? "pending" : attachment_id.asString())              << " on point " << (S32)attach_point << LL_ENDL; -        mSimAttachments[attachment_id] = attach_point; +        if (attachment_id.notNull()) +        { +            mSimAttachments[attachment_id] = attach_point; +        } +        else +        { +            // at the moment viewer is only interested in non-null attachments +            LL_DEBUGS("AVAppearanceAttachments") << "AV " << getID() +                << " has null attachment on point " << (S32)attach_point +                << ", discarding" << LL_ENDL; +        }      }      // todo? Doesn't detect if attachments were switched @@ -11709,4 +11740,8 @@ F32 LLVOAvatar::getAverageGPURenderTime()      return ret;  } +bool LLVOAvatar::isBuddy() const +{ +    return LLAvatarTracker::instance().isBuddy(getID()); +}  diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index f83ea59080..e5d232b792 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -253,6 +253,7 @@ public:  	virtual bool 	isControlAvatar() const { return mIsControlAvatar; } // True if this avatar is a control av (no associated user)  	virtual bool 	isUIAvatar() const { return mIsUIAvatar; } // True if this avatar is a supplemental av used in some UI views (no associated user) +    virtual bool 	isBuddy() const;  	// If this is an attachment, return the avatar it is attached to. Otherwise NULL.  	virtual const LLVOAvatar *getAttachedAvatar() const { return NULL; } @@ -424,7 +425,6 @@ protected:  private:  	bool			mFirstFullyVisible;      F32				mFirstDecloudTime; -	F32				mFirstUseDelaySeconds;  	LLFrameTimer	mFirstAppearanceMessageTimer;  	bool			mFullyLoaded; diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index c7b61edd1c..46bac63d93 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -110,6 +110,7 @@ private:  public:  	/*virtual*/ bool 	isSelf() const { return true; } +        virtual bool 	isBuddy() const { return false; }  	/*virtual*/ bool	isValid() const;  	//-------------------------------------------------------------------- diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 9697774fd9..9b2f644003 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3940,6 +3940,16 @@ function="World.EnvPreset"                       function="ToggleControl"                       parameter="AllowSelectAvatar" />                  </menu_item_check> +                <menu_item_check +                 label="Render Only Friends" +                 name="Render Only Friends"> +                    <menu_item_check.on_check +                     function="CheckControl" +                     parameter="RenderAvatarFriendsOnly" /> +                    <menu_item_check.on_click +                     function="ToggleControl" +                     parameter="RenderAvatarFriendsOnly" /> +                </menu_item_check>              </menu>              <menu               create_jump_keys="true" | 
