Merge branch 'develop' of https://github.com/secondlife/viewer
# Conflicts: # .github/pull_request_template.md # indra/newview/llmutelist.cpp # indra/newview/lltoolpie.cpp # indra/newview/llvoavatar.cpp # indra/newview/skins/default/xui/en/panel_preferences_sound.xmlmaster
commit
1829d9083d
|
|
@ -1230,12 +1230,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
|
|||
{
|
||||
gAgentAvatarp->setCompositeUpdatesEnabled(true);
|
||||
|
||||
// If we have not yet declouded, we may want to use
|
||||
// If we have not yet loaded core parts, we may want to use
|
||||
// baked texture UUIDs sent from the first objectUpdate message
|
||||
// don't overwrite these. If we have already declouded, we've saved
|
||||
// these ids as the last known good textures and can invalidate without
|
||||
// re-clouding.
|
||||
if (!gAgentAvatarp->getIsCloud())
|
||||
// don't overwrite these. If we have parts already, we've saved
|
||||
// these texture ids as the last known good textures and can
|
||||
// invalidate without having to recloud avatar.
|
||||
if (!gAgentAvatarp->getHasMissingParts())
|
||||
{
|
||||
gAgentAvatarp->invalidateAll();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -865,7 +865,7 @@ void LLWearableHoldingPattern::checkMissingWearables()
|
|||
// was requested but none was found, create a default asset as a replacement.
|
||||
// In all other cases, don't do anything.
|
||||
// For critical types (shape/hair/skin/eyes), this will keep the avatar as a cloud
|
||||
// due to logic in LLVOAvatarSelf::getIsCloud().
|
||||
// due to logic in LLVOAvatarSelf::getHasMissingParts().
|
||||
// For non-critical types (tatoo, socks, etc.) the wearable will just be missing.
|
||||
(requested_by_type[type] > 0) &&
|
||||
((type == LLWearableType::WT_PANTS) || (type == LLWearableType::WT_SHIRT) || (type == LLWearableType::WT_SKIRT)))
|
||||
|
|
|
|||
|
|
@ -1927,14 +1927,15 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim)
|
|||
if (!match.isUndefined())
|
||||
{
|
||||
mSearchResults->selectByValue(match);
|
||||
mSearchResults->setFocus(true);
|
||||
onCommitSearchResult();
|
||||
}
|
||||
// else select first found item
|
||||
// else let user decide
|
||||
else
|
||||
{
|
||||
mSearchResults->selectFirstItem();
|
||||
mSearchResults->operateOnAll(LLCtrlListInterface::OP_DESELECT);
|
||||
mSearchResults->setFocus(true);
|
||||
}
|
||||
mSearchResults->setFocus(true);
|
||||
onCommitSearchResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2273,10 +2273,10 @@ void LLIMProcessing::requestOfflineMessages()
|
|||
if (!requested
|
||||
&& gMessageSystem
|
||||
&& !gDisconnected
|
||||
&& LLMuteList::getInstance()->isLoaded()
|
||||
&& isAgentAvatarValid()
|
||||
&& gAgent.getRegion()
|
||||
&& gAgent.getRegion()->capabilitiesReceived())
|
||||
&& gAgent.getRegion()->capabilitiesReceived()
|
||||
&& (LLMuteList::getInstance()->isLoaded() || LLMuteList::getInstance()->getLoadFailed()))
|
||||
{
|
||||
std::string cap_url = gAgent.getRegionCapability("ReadOfflineMsgs");
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,8 @@ std::string LLMute::getDisplayType() const
|
|||
// LLMuteList()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLMuteList::LLMuteList() :
|
||||
mIsLoaded(false)
|
||||
mLoadState(ML_INITIAL),
|
||||
mRequestStartTime(0.f)
|
||||
{
|
||||
gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList);
|
||||
|
||||
|
|
@ -212,6 +213,23 @@ bool LLMuteList::isLinden(const std::string& name)
|
|||
return last_name == "linden";
|
||||
}
|
||||
|
||||
bool LLMuteList::getLoadFailed() const
|
||||
{
|
||||
if (mLoadState == ML_FAILED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (mLoadState == ML_REQUESTED)
|
||||
{
|
||||
constexpr F64 WAIT_SECONDS = 30;
|
||||
if (mRequestStartTime + WAIT_SECONDS < LLTimer::getTotalSeconds())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static LLVOAvatar* find_avatar(const LLUUID& id)
|
||||
{
|
||||
LLViewerObject *obj = gObjectList.findObject(id);
|
||||
|
|
@ -389,11 +407,14 @@ void LLMuteList::updateAdd(const LLMute& mute, bool show_message /* = true */)
|
|||
msg->addU32("MuteFlags", mute.mFlags);
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
if (!mIsLoaded)
|
||||
if (!isLoaded())
|
||||
{
|
||||
LL_WARNS() << "Added elements to non-initialized block list" << LL_ENDL;
|
||||
}
|
||||
mIsLoaded = true; // why is this here? -MG
|
||||
// Based of logs and testing, if file doesn't exist server side,
|
||||
// viewer will not receive any callback and won't know to set
|
||||
// ML_LOADED. As a workaround, set it regardless of current state.
|
||||
mLoadState = ML_LOADED;
|
||||
|
||||
// <FS:Ansariel> FIRE-15746: Show block report in nearby chat
|
||||
if (show_message && gSavedSettings.getBOOL("FSReportBlockToNearbyChat"))
|
||||
|
|
@ -609,6 +630,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)
|
|||
if(!filename.size())
|
||||
{
|
||||
LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL;
|
||||
mLoadState = ML_FAILED;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -616,6 +638,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)
|
|||
if (!fp)
|
||||
{
|
||||
LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL;
|
||||
mLoadState = ML_FAILED;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -791,13 +814,17 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)
|
|||
if (gDisconnected)
|
||||
{
|
||||
LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL;
|
||||
mLoadState = ML_FAILED;
|
||||
return;
|
||||
}
|
||||
if (!gAgent.getRegion())
|
||||
{
|
||||
LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL;
|
||||
mLoadState = ML_FAILED;
|
||||
return;
|
||||
}
|
||||
mLoadState = ML_REQUESTED;
|
||||
mRequestStartTime = LLTimer::getElapsedSeconds();
|
||||
// Double amount of retries due to this request happening during busy stage
|
||||
// Ideally this should be turned into a capability
|
||||
gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, true, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
|
||||
|
|
@ -810,7 +837,7 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)
|
|||
void LLMuteList::cache(const LLUUID& agent_id)
|
||||
{
|
||||
// Write to disk even if empty.
|
||||
if(mIsLoaded)
|
||||
if(isLoaded())
|
||||
{
|
||||
std::string agent_id_string;
|
||||
std::string filename;
|
||||
|
|
@ -838,6 +865,13 @@ void LLMuteList::processMuteListUpdate(LLMessageSystem* msg, void**)
|
|||
msg->getStringFast(_PREHASH_MuteData, _PREHASH_Filename, unclean_filename);
|
||||
std::string filename = LLDir::getScrubbedFileName(unclean_filename);
|
||||
|
||||
LLMuteList* mute_list = getInstance();
|
||||
mute_list->mLoadState = ML_REQUESTED;
|
||||
mute_list->mRequestStartTime = LLTimer::getElapsedSeconds();
|
||||
|
||||
// Todo: Based of logs and testing, there is no callback
|
||||
// from server if file doesn't exist server side.
|
||||
// Once server side gets fixed make sure it gets handled right.
|
||||
std::string *local_filename_and_path = new std::string(gDirUtilp->getExpandedFilename( LL_PATH_CACHE, filename ));
|
||||
gXferManager->requestFile(*local_filename_and_path,
|
||||
filename,
|
||||
|
|
@ -870,12 +904,16 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_
|
|||
LLMuteList::getInstance()->loadFromFile(*local_filename_and_path);
|
||||
LLFile::remove(*local_filename_and_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLMuteList::getInstance()->mLoadState = ML_FAILED;
|
||||
}
|
||||
delete local_filename_and_path;
|
||||
}
|
||||
|
||||
void LLMuteList::onAccountNameChanged(const LLUUID& id, const std::string& username)
|
||||
{
|
||||
if (mIsLoaded)
|
||||
if (isLoaded())
|
||||
{
|
||||
LLMute mute(id, username, LLMute::AGENT);
|
||||
mute_set_t::iterator mute_it = mMutes.find(mute);
|
||||
|
|
@ -927,7 +965,7 @@ void LLMuteList::removeObserver(LLMuteListObserver* observer)
|
|||
|
||||
void LLMuteList::setLoaded()
|
||||
{
|
||||
mIsLoaded = true;
|
||||
mLoadState = ML_LOADED;
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,14 @@ class LLMuteList : public LLSingleton<LLMuteList>
|
|||
LLSINGLETON(LLMuteList);
|
||||
~LLMuteList();
|
||||
/*virtual*/ void cleanupSingleton() override;
|
||||
|
||||
enum EMuteListState
|
||||
{
|
||||
ML_INITIAL,
|
||||
ML_REQUESTED,
|
||||
ML_LOADED,
|
||||
ML_FAILED,
|
||||
};
|
||||
public:
|
||||
// reasons for auto-unmuting a resident
|
||||
enum EAutoReason
|
||||
|
|
@ -107,7 +115,8 @@ public:
|
|||
|
||||
static bool isLinden(const std::string& name);
|
||||
|
||||
bool isLoaded() const { return mIsLoaded; }
|
||||
bool isLoaded() const { return mLoadState == ML_LOADED; }
|
||||
bool getLoadFailed() const;
|
||||
|
||||
std::vector<LLMute> getMutes() const;
|
||||
|
||||
|
|
@ -170,7 +179,8 @@ private:
|
|||
typedef std::set<LLMuteListObserver*> observer_set_t;
|
||||
observer_set_t mObservers;
|
||||
|
||||
bool mIsLoaded;
|
||||
EMuteListState mLoadState;
|
||||
F64 mRequestStartTime;
|
||||
|
||||
friend class LLDispatchEmptyMuteList;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,10 +34,12 @@
|
|||
#include "llaccordionctrl.h"
|
||||
#include "llaccordionctrltab.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llaisapi.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llinspecttexture.h"
|
||||
#include "llinventorymodelbackgroundfetch.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llmenubutton.h"
|
||||
|
|
@ -218,12 +220,22 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
|
|||
|
||||
list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
|
||||
|
||||
// Fetch the new outfit contents.
|
||||
cat->fetch();
|
||||
|
||||
// Refresh the list of outfit items after fetch().
|
||||
// Further list updates will be triggered by the category observer.
|
||||
list->updateList(cat_id);
|
||||
if (AISAPI::isAvailable() && LLInventoryModelBackgroundFetch::instance().folderFetchActive())
|
||||
{
|
||||
// for reliability just fetch it whole, linked items included
|
||||
LLInventoryModelBackgroundFetch::instance().fetchFolderAndLinks(cat_id, [cat_id, list]
|
||||
{
|
||||
if (list) list->updateList(cat_id);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fetch the new outfit contents.
|
||||
cat->fetch();
|
||||
// Refresh the list of outfit items after fetch().
|
||||
// Further list updates will be triggered by the category observer.
|
||||
list->updateList(cat_id);
|
||||
}
|
||||
|
||||
// If filter is currently applied we store the initial tab state.
|
||||
if (!getFilterSubString().empty())
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ LLRender::eTexIndex LLPanelFace::getMatTextureChannel()
|
|||
return LLRender::NORMAL_MAP;
|
||||
break;
|
||||
case MATTYPE_SPECULAR: // "Shininess (specular)"
|
||||
if (getCurrentNormalMap().notNull())
|
||||
if (getCurrentSpecularMap().notNull())
|
||||
return LLRender::SPECULAR_MAP;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1963,7 +1963,7 @@ bool LLToolPie::shouldAllowFirstMediaInteraction(const LLPickInfo& pick, bool mo
|
|||
return false;
|
||||
}
|
||||
// Any object with PRIM_MEDIA_FIRST_CLICK_INTERACT set to TRUE
|
||||
if ((FirstClickPref & MEDIA_FIRST_CLICK_ANY) == MEDIA_FIRST_CLICK_ANY)
|
||||
if((FirstClickPref & MEDIA_FIRST_CLICK_ANY) == MEDIA_FIRST_CLICK_ANY)
|
||||
{
|
||||
LL_DEBUGS_ONCE() << "FirstClickPref & MEDIA_FIRST_CLICK_ANY" << LL_ENDL;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ public:
|
|||
MEDIA_FIRST_CLICK_NONE = 0, // Special case: Feature is disabled
|
||||
MEDIA_FIRST_CLICK_HUD = 1 << 0, // 0b00000001 (1)
|
||||
MEDIA_FIRST_CLICK_OWN = 1 << 1, // 0b00000010 (2)
|
||||
MEDIA_FIRST_CLICK_GROUP = 1 << 2, // 0b00000100 (4)
|
||||
MEDIA_FIRST_CLICK_FRIEND = 1 << 3, // 0b00001000 (8)
|
||||
MEDIA_FIRST_CLICK_FRIEND = 1 << 2, // 0b00000100 (4)
|
||||
MEDIA_FIRST_CLICK_GROUP = 1 << 3, // 0b00001000 (8)
|
||||
MEDIA_FIRST_CLICK_LAND = 1 << 4, // 0b00010000 (16)
|
||||
|
||||
// Covers any object with PRIM_MEDIA_FIRST_CLICK_INTERACT (combines all previous flags)
|
||||
|
|
|
|||
|
|
@ -720,6 +720,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
|
|||
mVisuallyMuteSetting(AV_RENDER_NORMALLY),
|
||||
mMutedAVColor(LLColor4::white /* used for "uninitialize" */),
|
||||
mFirstFullyVisible(true),
|
||||
mWaitingForMeshes(false),
|
||||
mFirstDecloudTime(-1.f),
|
||||
mFullyLoaded(false),
|
||||
mPreviousFullyLoaded(false),
|
||||
|
|
@ -1011,12 +1012,12 @@ bool LLVOAvatar::isFullyTextured() const
|
|||
|
||||
bool LLVOAvatar::hasGray() const
|
||||
{
|
||||
return !getIsCloud() && !isFullyTextured();
|
||||
return !getHasMissingParts() && !isFullyTextured();
|
||||
}
|
||||
|
||||
S32 LLVOAvatar::getRezzedStatus() const
|
||||
{
|
||||
if (getIsCloud()) return 0;
|
||||
if (getHasMissingParts()) return 0;
|
||||
bool textured = isFullyTextured();
|
||||
bool all_baked_loaded = allBakedTexturesCompletelyDownloaded();
|
||||
if (textured && all_baked_loaded && getAttachmentCount() == mSimAttachments.size()) return 4;
|
||||
|
|
@ -1063,30 +1064,45 @@ bool LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)
|
|||
}
|
||||
|
||||
// static
|
||||
void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars)
|
||||
void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars)
|
||||
{
|
||||
counts.clear();
|
||||
counts.resize(5);
|
||||
avg_cloud_time = 0;
|
||||
cloud_avatars = 0;
|
||||
pending_meshes = 0;
|
||||
control_avatars = 0;
|
||||
S32 count_avg = 0;
|
||||
|
||||
for (LLCharacter* character : LLCharacter::sInstances)
|
||||
{
|
||||
if (LLVOAvatar* inst = (LLVOAvatar*)character)
|
||||
LLVOAvatar* inst = (LLVOAvatar*)character;
|
||||
if (inst && !inst->isUIAvatar() && !inst->isSelf())
|
||||
{
|
||||
S32 rez_status = inst->getRezzedStatus();
|
||||
counts[rez_status]++;
|
||||
F32 time = inst->getFirstDecloudTime();
|
||||
if (time >= 0)
|
||||
if (inst->isControlAvatar())
|
||||
{
|
||||
avg_cloud_time+=time;
|
||||
count_avg++;
|
||||
control_avatars++;
|
||||
}
|
||||
if (!inst->isFullyLoaded() || time < 0)
|
||||
else
|
||||
{
|
||||
// still renders as cloud
|
||||
cloud_avatars++;
|
||||
S32 rez_status = inst->getRezzedStatus();
|
||||
counts[rez_status]++;
|
||||
F32 time = inst->getFirstDecloudTime();
|
||||
if (time >= 0)
|
||||
{
|
||||
avg_cloud_time += time;
|
||||
count_avg++;
|
||||
}
|
||||
if (!inst->isFullyLoaded() || time < 0)
|
||||
{
|
||||
// still renders as cloud
|
||||
cloud_avatars++;
|
||||
if (rez_status >= 4
|
||||
&& inst->mWaitingForMeshes)
|
||||
{
|
||||
pending_meshes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1103,7 +1119,7 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status)
|
|||
switch (rez_status)
|
||||
{
|
||||
case 0:
|
||||
return "cloud";
|
||||
return "missing parts";
|
||||
case 1:
|
||||
return "gray";
|
||||
case 2:
|
||||
|
|
@ -3972,7 +3988,7 @@ void LLVOAvatar::idleUpdateNameTagText(bool new_name)
|
|||
// [RLVa:KB] - Checked: RLVa-1.2.2
|
||||
bool is_friend = fRlvShowAvName && isBuddy();
|
||||
// [/RLVa:KB]
|
||||
bool is_cloud = getIsCloud();
|
||||
bool is_cloud = getHasMissingParts();
|
||||
|
||||
if (is_appearance != mNameAppearance)
|
||||
{
|
||||
|
|
@ -8764,102 +8780,100 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
|
|||
}
|
||||
}
|
||||
|
||||
// <FS:Beq> remove mesh rezzing delay
|
||||
// //bool check_object_for_mesh_loading(LLViewerObject* objectp)
|
||||
//{
|
||||
// if (!objectp || !objectp->getVolume())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// LLVolume* volp = objectp->getVolume();
|
||||
// const LLUUID& mesh_id = volp->getParams().getSculptID();
|
||||
// if (mesh_id.isNull())
|
||||
// {
|
||||
// // No mesh nor skin info needed
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (volp->isMeshAssetUnavaliable())
|
||||
// {
|
||||
// // Mesh failed to load, do not expect it
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (!objectp->mDrawable)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// LLVOVolume* pvobj = objectp->mDrawable->getVOVolume();
|
||||
// if (pvobj)
|
||||
// {
|
||||
// if (!pvobj->isMesh())
|
||||
// {
|
||||
// // Not a mesh
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (!volp->isMeshAssetLoaded())
|
||||
// {
|
||||
// // Waiting for mesh
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo();
|
||||
// if (skin_data)
|
||||
// {
|
||||
// // Skin info present, done
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (pvobj->isSkinInfoUnavaliable())
|
||||
// {
|
||||
// // Load failed or info not present, don't expect it
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // object is not ready
|
||||
// return true;
|
||||
//}
|
||||
//
|
||||
//bool LLVOAvatar::hasPendingAttachedMeshes()
|
||||
//{
|
||||
// for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
|
||||
// iter != mAttachmentPoints.end();
|
||||
// ++iter)
|
||||
// {
|
||||
// LLViewerJointAttachment* attachment = iter->second;
|
||||
// if (attachment)
|
||||
// {
|
||||
// for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
// attachment_iter != attachment->mAttachedObjects.end();
|
||||
// ++attachment_iter)
|
||||
// {
|
||||
// LLViewerObject* objectp = attachment_iter->get();
|
||||
// if (objectp && !objectp->isDead())
|
||||
// {
|
||||
// if (check_object_for_mesh_loading(objectp))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
|
||||
// for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
|
||||
// iter1 != child_list.end(); ++iter1)
|
||||
// {
|
||||
// LLViewerObject* objectchild = *iter1;
|
||||
// if (check_object_for_mesh_loading(objectchild))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
// </FS:Beq>
|
||||
bool check_object_for_mesh_loading(LLViewerObject* objectp)
|
||||
{
|
||||
if (!objectp || !objectp->getVolume())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
LLVolume* volp = objectp->getVolume();
|
||||
const LLUUID& mesh_id = volp->getParams().getSculptID();
|
||||
if (mesh_id.isNull())
|
||||
{
|
||||
// No mesh nor skin info needed
|
||||
return false;
|
||||
}
|
||||
|
||||
if (volp->isMeshAssetUnavaliable())
|
||||
{
|
||||
// Mesh failed to load, do not expect it
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!objectp->mDrawable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLVOVolume* pvobj = objectp->mDrawable->getVOVolume();
|
||||
if (pvobj)
|
||||
{
|
||||
if (!pvobj->isMesh())
|
||||
{
|
||||
// Not a mesh
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!volp->isMeshAssetLoaded())
|
||||
{
|
||||
// Waiting for mesh
|
||||
return true;
|
||||
}
|
||||
|
||||
const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo();
|
||||
if (skin_data)
|
||||
{
|
||||
// Skin info present, done
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pvobj->isSkinInfoUnavaliable())
|
||||
{
|
||||
// Load failed or info not present, don't expect it
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// object is not ready
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLVOAvatar::hasPendingAttachedMeshes()
|
||||
{
|
||||
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
|
||||
iter != mAttachmentPoints.end();
|
||||
++iter)
|
||||
{
|
||||
LLViewerJointAttachment* attachment = iter->second;
|
||||
if (attachment)
|
||||
{
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
attachment_iter != attachment->mAttachedObjects.end();
|
||||
++attachment_iter)
|
||||
{
|
||||
LLViewerObject* objectp = attachment_iter->get();
|
||||
if (objectp && !objectp->isDead())
|
||||
{
|
||||
if (check_object_for_mesh_loading(objectp))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
|
||||
for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
|
||||
iter1 != child_list.end(); ++iter1)
|
||||
{
|
||||
LLViewerObject* objectchild = *iter1;
|
||||
if (check_object_for_mesh_loading(objectchild))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// detachObject()
|
||||
|
|
@ -9332,7 +9346,7 @@ bool LLVOAvatar::isVisible() const
|
|||
}
|
||||
|
||||
// Determine if we have enough avatar data to render
|
||||
bool LLVOAvatar::getIsCloud() const
|
||||
bool LLVOAvatar::getHasMissingParts() const
|
||||
{
|
||||
if (mIsDummy)
|
||||
{
|
||||
|
|
@ -9541,8 +9555,12 @@ bool LLVOAvatar::updateIsFullyLoaded()
|
|||
|| (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC)
|
||||
|| !mPendingAttachment.empty()
|
||||
|| (rez_status < 3 && !isFullyBaked())
|
||||
// || hasPendingAttachedMeshes() // <FS:Beq/>
|
||||
);
|
||||
if (!loading)
|
||||
{
|
||||
mWaitingForMeshes = hasPendingAttachedMeshes();
|
||||
loading = mWaitingForMeshes;
|
||||
}
|
||||
|
||||
// compare amount of attachments to one reported by simulator
|
||||
if (!isSelf() && mLastCloudAttachmentCount < mSimAttachments.size() && mSimAttachments.size() > 0)
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ public:
|
|||
|
||||
virtual bool isTooComplex() const; // <FS:Ansariel> FIRE-29012: Standalone animesh avatars get affected by complexity limit; changed to virtual
|
||||
bool visualParamWeightsAreDefault();
|
||||
virtual bool getIsCloud() const;
|
||||
virtual bool getHasMissingParts() const;
|
||||
bool isFullyTextured() const;
|
||||
bool hasGray() const;
|
||||
S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded.
|
||||
|
|
@ -443,6 +443,7 @@ protected:
|
|||
|
||||
private:
|
||||
bool mFirstFullyVisible;
|
||||
bool mWaitingForMeshes;
|
||||
F32 mFirstDecloudTime;
|
||||
LLFrameTimer mFirstAppearanceMessageTimer;
|
||||
|
||||
|
|
@ -754,7 +755,7 @@ public:
|
|||
|
||||
bool isFullyBaked();
|
||||
static bool areAllNearbyInstancesBaked(S32& grey_avatars);
|
||||
static void getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars);
|
||||
static void getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars);
|
||||
static std::string rezStatusToString(S32 status);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -980,7 +981,7 @@ public:
|
|||
virtual bool detachObject(LLViewerObject *viewer_object);
|
||||
static bool getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id );
|
||||
void cleanupAttachedMesh( LLViewerObject* pVO );
|
||||
// bool hasPendingAttachedMeshes(); // <FS:Beq/> remove mesh rezzing delay
|
||||
bool hasPendingAttachedMeshes();
|
||||
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
|
||||
/*virtual*/ bool isWearingWearableType(LLWearableType::EType type ) const;
|
||||
LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const;
|
||||
|
|
|
|||
|
|
@ -2486,7 +2486,7 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()
|
|||
LL_INFOS() << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << LL_ENDL;
|
||||
}
|
||||
|
||||
bool LLVOAvatarSelf::getIsCloud() const
|
||||
bool LLVOAvatarSelf::getHasMissingParts() const
|
||||
{
|
||||
// Let people know why they're clouded without spamming them into oblivion.
|
||||
bool do_warn = false;
|
||||
|
|
@ -2796,14 +2796,18 @@ void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url)
|
|||
std::vector<S32> rez_counts;
|
||||
F32 avg_time;
|
||||
S32 total_cloud_avatars;
|
||||
LLVOAvatar::getNearbyRezzedStats(rez_counts, avg_time, total_cloud_avatars);
|
||||
S32 waiting_for_meshes;
|
||||
S32 control_avatars;
|
||||
LLVOAvatar::getNearbyRezzedStats(rez_counts, avg_time, total_cloud_avatars, waiting_for_meshes, control_avatars);
|
||||
for (S32 rez_stat = 0; rez_stat < rez_counts.size(); ++rez_stat)
|
||||
{
|
||||
std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
|
||||
msg["nearby"][rez_status_name] = rez_counts[rez_stat];
|
||||
}
|
||||
msg["nearby"]["waiting_for_meshes"] = waiting_for_meshes;
|
||||
msg["nearby"]["avg_decloud_time"] = avg_time;
|
||||
msg["nearby"]["cloud_total"] = total_cloud_avatars;
|
||||
msg["nearby"]["animeshes"] = control_avatars;
|
||||
|
||||
// std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
|
||||
std::vector<std::string> by_fields;
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ public:
|
|||
// Loading state
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
/*virtual*/ bool getIsCloud() const;
|
||||
/*virtual*/ bool getHasMissingParts() const;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Region state
|
||||
|
|
|
|||
|
|
@ -43,12 +43,15 @@ namespace LLStatViewer
|
|||
LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample");
|
||||
}
|
||||
|
||||
void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars)
|
||||
void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars)
|
||||
{
|
||||
counts.resize(3);
|
||||
counts[0] = 0;
|
||||
counts[1] = 0;
|
||||
counts[2] = 1;
|
||||
cloud_avatars = 0;
|
||||
pending_meshes = 0;
|
||||
control_avatars = 0;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
Loading…
Reference in New Issue