Merge viewer-neko

master
Ansariel 2019-10-09 22:05:52 +02:00
commit 146d527104
16 changed files with 157 additions and 132 deletions

View File

@ -186,12 +186,17 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
list(GET LL_BUILD_LIST "${sysroot_idx}" CMAKE_OSX_SYSROOT)
message(STATUS "CMAKE_OSX_SYSROOT = '${CMAKE_OSX_SYSROOT}'")
set(XCODE_VERSION 7.0)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")
set(CMAKE_XCODE_ATTRIBUTE_GCC_STRICT_ALIASING NO)
set(CMAKE_XCODE_ATTRIBUTE_GCC_FAST_MATH NO)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS ssse3)
# we must hard code this to off for now. xcode's built in signing does not
# handle embedded app bundles such as CEF and others. Any signing for local
# development must be done after the build as we do in viewer_manifest.py for
# released builds
# https://stackoverflow.com/a/54296008
# "-" represents "Sign to Run Locally" and empty string represents "Do Not Sign"
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
set(CMAKE_OSX_ARCHITECTURES "${ARCH}")
string(REPLACE "i686" "i386" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}")

View File

@ -826,8 +826,6 @@ attributedStringInfo getSegments(NSAttributedString *str)
[super setMarkedText:aString selectedRange:selectedRange replacementRange:replacementRange];
if ([aString length] == 0) // this means Input Widow becomes empty
{
//[_window orderOut:_window]; // Close this to avoid empty Input Window
// <FS:TS> Xcode 11 compile fix
[self.window orderOut:self.window]; // Close this to avoid empty Input Window
}
}
@ -852,8 +850,6 @@ attributedStringInfo getSegments(NSAttributedString *str)
(mKeyPressed >= 0xF700 && mKeyPressed <= 0xF8FF))
{
// this is case a) of above comment
// <FS:TS> Xcode 11 compile fix
//[_window orderOut:_window]; // to avoid empty Input Window
[self.window orderOut:self.window]; // to avoid empty Input Window
}
}

View File

@ -1687,8 +1687,12 @@ if (DARWIN)
PROPERTIES
COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
# BugsplatMac is a module, imported with @import. That language feature
# demands these switches.
COMPILE_FLAGS "-fmodules -fcxx-modules"
# demands these -f switches.
# Xcode 10.2 requires that Objective-C++ headers declare nullability of
# pointer variables. As of 2019-06-26, the BugsplatMac version we're using
# does not yet do so in its own header files. This -W flag prevents fatal
# warnings.
COMPILE_FLAGS "-fmodules -fcxx-modules -Wno-nullability-completeness"
)
# [FS] Growl libs

View File

@ -29,8 +29,10 @@
#include "llaudiosourcevo.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llmutelist.h"
#include "llviewercontrol.h"
#include "llviewerparcelmgr.h"
LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp)
@ -57,6 +59,79 @@ void LLAudioSourceVO::setGain(const F32 gain)
mGain = llclamp(gain, 0.f, 1.f);
}
void LLAudioSourceVO::checkCutOffRadius()
{
if (mSourceMuted // already muted by something, will be recalculated on update()
|| !mObjectp)
{
return;
}
F32 cutoff = mObjectp->getSoundCutOffRadius();
if (cutoff < 0.1f)
{
// consider cutoff below 0.1m as off (to avoid near zero comparison)
return;
}
LLVector3d pos_global = getPosGlobal();
if (!isInCutOffRadius(pos_global, cutoff))
{
mSourceMuted = true;
}
}
LLVector3d LLAudioSourceVO::getPosGlobal() const
{
if (mObjectp->isAttachment())
{
LLViewerObject* parent = mObjectp;
while (parent && !parent->isAvatar())
{
parent = (LLViewerObject*)parent->getParent();
}
if (parent)
{
return parent->getPositionGlobal();
}
}
else
{
return mObjectp->getPositionGlobal();
}
return LLVector3d();
}
bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const
{
static LLCachedControl<S32> ear_mode(gSavedSettings, "VoiceEarLocation", 0);
LLVector3d pos_ear;
switch (ear_mode())
{
case 0: // camera
pos_ear = gAgentCamera.getCameraPositionGlobal();
break;
case 1: // avatar
case 2:
// voice support 'mixed' in '2' case with agent's position and camera's rotations
// but it is not defined in settings and uses camera as default
pos_ear = gAgent.getPositionGlobal();
break;
default:
pos_ear = gAgentCamera.getCameraPositionGlobal();
break;
}
LLVector3d to_vec = pos_global - pos_ear;
F32 dist = (F32)to_vec.magVec();
return dist < cutoff;
}
void LLAudioSourceVO::updateMute()
{
if (!mObjectp || mObjectp->isDead())
@ -66,26 +141,11 @@ void LLAudioSourceVO::updateMute()
}
bool mute = false;
LLVector3d pos_global;
LLVector3d pos_global = getPosGlobal();
if (mObjectp->isAttachment())
{
LLViewerObject* parent = mObjectp;
while (parent && !parent->isAvatar())
{
parent = (LLViewerObject*)parent->getParent();
}
if (parent)
{
pos_global = parent->getPositionGlobal();
}
}
else
{
pos_global = mObjectp->getPositionGlobal();
}
if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
F32 cutoff = mObjectp->getSoundCutOffRadius();
if ((cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff)) // consider cutoff below 0.1m as off
|| !LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
{
mute = true;
}

View File

@ -41,7 +41,11 @@ public:
/*virtual*/ void update();
/*virtual*/ void setGain(const F32 gain);
void checkCutOffRadius();
private:
LLVector3d getPosGlobal() const;
bool isInCutOffRadius(LLVector3d pos_global, const F32 cutoff) const;
void updateMute();
private:

View File

@ -177,7 +177,7 @@ BOOL LLConversationViewSession::postBuild()
LLAvatarIconCtrl* icon = mItemPanel->getChild<LLAvatarIconCtrl>("avatar_icon");
icon->setVisible(true);
icon->setValue(session->mOtherParticipantID);
mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID, true);
mSpeakingIndicator->setSpeakerId(session->mOtherParticipantID, session->mSessionID, true);
mHasArrow = false;
}
break;

View File

@ -1346,41 +1346,18 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
}
else // IM_TASK_INVENTORY_OFFERED
{
if (offline == IM_OFFLINE && session_id.isNull() && aux_id.notNull() && binary_bucket_size > sizeof(S8)* 5)
{
// cap received offline message
std::string str_bucket = ll_safe_string((char*)binary_bucket, binary_bucket_size);
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
tokenizer tokens(str_bucket, sep);
tokenizer::iterator iter = tokens.begin();
info->mType = (LLAssetType::EType)(atoi((*(iter++)).c_str()));
// Note There is more elements in 'tokens' ...
info->mObjectID = LLUUID::null;
info->mFromObject = TRUE;
}
else
{
if (sizeof(S8) != binary_bucket_size)
{
LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
delete info;
// <FS:Ansariel> Don't flash task icon
//break;
return;
}
info->mType = (LLAssetType::EType) binary_bucket[0];
info->mObjectID = LLUUID::null;
info->mFromObject = TRUE;
}
info->mType = (LLAssetType::EType) binary_bucket[0];
info->mObjectID = LLUUID::null;
info->mFromObject = TRUE;
}
// In the case of an offline message, the transaction id will be in aux_id and th session_id will be null
// (conversely when online the transaction id is passed as session_id)
info->mTransactionID = session_id.isNull() ? aux_id : session_id;
info->mIM = dialog;
info->mFromID = from_id;
info->mFromGroup = from_group;
info->mTransactionID = session_id;
info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
info->mFromName = name;

View File

@ -720,7 +720,7 @@ void LLNetMap::draw()
pos_map = globalPosToView(positions[i]);
// <FS:Ansariel> Check for unknown Z-offset => AVATAR_UNKNOWN_Z_OFFSET
//unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z &&
//unknown_relative_z = positions[i].mdV[VZ] >= COARSEUPDATE_MAX_Z &&
// camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z;
unknown_relative_z = false;
if (positions[i].mdV[VZ] == AVATAR_UNKNOWN_Z_OFFSET)

View File

@ -277,15 +277,15 @@ void LLOutputMonitorCtrl::draw()
BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
{
// <FS:Ansariel> Show voice volume instead of an empty floater
//if (mSpeakerId != gAgentID && !mShowParticipantsSpeaking)
//if (mSpeakerId != gAgentID)
if (mSpeakerId.notNull() && mSpeakerId != gAgentID && !mShowParticipantsSpeaking)
// </FS:Ansariel>
{
LLFloaterReg::showInstance("floater_voice_volume", LLSD().with("avatar_id", mSpeakerId));
}
// <FS:Ansariel> Show voice volume instead of an empty floater
//else if(mShowParticipantsSpeaking)
else if(mShowParticipantsSpeaking || mSpeakerId.isNull())
//else if (mShowParticipantsSpeaking)
else if (mShowParticipantsSpeaking || mSpeakerId.isNull())
// </FS:Ansariel>
{
LLFloaterReg::showInstance("chat_voice", LLSD());

View File

@ -402,6 +402,7 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
previewEditor->onSpellCheckSettingsChange();
preview->setEnabled(modifiable);
preview->syncExternal();
preview->mAssetStatus = PREVIEW_ASSET_LOADED;
}
else
@ -542,10 +543,6 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync)
}
editor->makePristine();
if (sync)
{
syncExternal();
}
const LLInventoryItem* item = getItem();
// save it out to database
if (item)
@ -797,6 +794,7 @@ void LLPreviewNotecard::openInExternalEditor()
// Start watching file changes.
mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLPreviewNotecard::onExternalChange, this, _1));
mLiveFile->ignoreNextUpdate();
mLiveFile->addToEventTimer();
// Open it in external editor.

View File

@ -65,6 +65,7 @@ F32 SHINE_WIDTH = 0.6f;
F32 SHINE_OPACITY = 0.3f;
F32 FALL_TIME = 0.6f;
S32 BORDER_WIDTH = 6;
S32 TOP_PANEL_HEIGHT = 30;
const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
@ -299,8 +300,8 @@ void LLSnapshotLivePreview::draw()
F32 uv_width = isImageScaled() ? 1.f : llmin((F32)getWidth() / (F32)getCurrentImage()->getWidth(), 1.f);
F32 uv_height = isImageScaled() ? 1.f : llmin((F32)getHeight() / (F32)getCurrentImage()->getHeight(), 1.f);
gGL.pushMatrix();
{
gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
{
gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom + TOP_PANEL_HEIGHT, 0.f);
// <FS:Ansariel> Remove QUADS rendering mode
//gGL.begin(LLRender::QUADS);
//{
@ -376,14 +377,15 @@ void LLSnapshotLivePreview::draw()
F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
// draw "shine" effect
LLLocalClipRect clip(getLocalRect());
LLRect local_rect(0, getRect().getHeight() + TOP_PANEL_HEIGHT, getRect().getWidth(), 0);
LLLocalClipRect clip(local_rect);
{
// draw diagonal stripe with gradient that passes over screen
S32 x1 = gViewerWindow->getWindowWidthScaled() * ll_round((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f)));
S32 x2 = x1 + ll_round(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
S32 x3 = x2 + ll_round(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
S32 y1 = 0;
S32 y2 = gViewerWindow->getWindowHeightScaled();
S32 y2 = gViewerWindow->getWindowHeightScaled() + TOP_PANEL_HEIGHT;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
// <FS:Ansariel> Remove QUADS rendering mode
@ -443,52 +445,6 @@ void LLSnapshotLivePreview::draw()
}
}
// draw framing rectangle
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4f(1.f, 1.f, 1.f, 1.f);
const LLRect& outline_rect = getImageRect();
// <FS:Ansariel> Remove QUADS rendering mode
//gGL.begin(LLRender::QUADS);
//{
// gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
// gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
// gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
// gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
// gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
// gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
// gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
// gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
// gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
// gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
// gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
// gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
// gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
// gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
// gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
// gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
//}
//gGL.end();
gGL.begin(LLRender::TRIANGLE_STRIP);
{
gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
}
gGL.end();
// </FS:Ansariel>
}
// draw old image dropping away
if (mFallAnimTimer.getStarted())
{

View File

@ -286,6 +286,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mData(NULL),
mAudioSourcep(NULL),
mAudioGain(1.f),
mSoundCutOffRadius(0.f),
mAppAngle(0.f),
mPixelArea(1024.f),
mInventory(NULL),
@ -1278,6 +1279,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
LLUUID audio_uuid;
LLUUID owner_id; // only valid if audio_uuid or particle system is not null
F32 gain;
F32 cutoff;
U8 sound_flags;
mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num);
@ -1286,6 +1288,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// HACK: Owner id only valid if non-null sound id or particle system
mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num );
mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num );
mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Radius, cutoff, block_num );
mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num );
mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Material, material, block_num );
mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num);
@ -1294,6 +1297,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
mTotalCRC = crc;
mSoundCutOffRadius = cutoff;
// Owner ID used for sound muting or particle system muting
setAttachedSound(audio_uuid, owner_id, gain, sound_flags);
@ -2002,6 +2006,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
mTotalCRC = crc;
mSoundCutOffRadius = cutoff;
setAttachedSound(sound_uuid, owner_id, gain, sound_flags);
@ -6047,6 +6052,8 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) )
{
//LL_INFOS() << "Playing attached sound " << audio_uuid << LL_ENDL;
// recheck cutoff radius in case this update was an object-update with new value
mAudioSourcep->checkCutOffRadius();
mAudioSourcep->play(audio_uuid);
}
}

View File

@ -410,6 +410,7 @@ public:
// Owner id is this object's owner
void setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags);
void adjustAudioGain(const F32 gain);
F32 getSoundCutOffRadius() const { return mSoundCutOffRadius; }
void clearAttachedSound() { mAudioSourcep = NULL; }
// Create if necessary
@ -807,6 +808,7 @@ protected:
LLPointer<LLViewerPartSourceScript> mPartSourcep; // Particle source associated with this object.
LLAudioSourceVO* mAudioSourcep;
F32 mAudioGain;
F32 mSoundCutOffRadius;
F32 mAppAngle; // Apparent visual arc in degrees
F32 mPixelArea; // Apparent area in pixels

View File

@ -922,8 +922,9 @@ BOOL LLVOAvatar::hasGray() const
S32 LLVOAvatar::getRezzedStatus() const
{
if (getIsCloud()) return 0;
if (isFullyTextured() && allBakedTexturesCompletelyDownloaded()) return 3;
if (isFullyTextured()) return 2;
bool textured = isFullyTextured();
if (textured && allBakedTexturesCompletelyDownloaded()) return 3;
if (textured) return 2;
llassert(hasGray());
return 1; // gray
}
@ -2146,8 +2147,10 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
LL_ERRS() << "Error resetting skeleton" << LL_ENDL;
}
// Reset attachment points (buildSkeleton only does bones and CVs)
bool ignore_hud_joints = true;
// Reset attachment points
// BuildSkeleton only does bones and CVs but we still need to reinit huds
// since huds can be animated.
bool ignore_hud_joints = !isSelf();
initAttachmentPoints(ignore_hud_joints);
// Fix up collision volumes
@ -7331,7 +7334,7 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints)
LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter;
if (info->mIsHUDAttachment && (!isSelf() || ignore_hud_joints))
{
//don't process hud joint for other avatars, or when doing a skeleton reset.
//don't process hud joint for other avatars.
continue;
}
@ -8482,14 +8485,13 @@ bool LLVOAvatar::getIsCloud() const
);
}
void LLVOAvatar::updateRezzedStatusTimers()
void LLVOAvatar::updateRezzedStatusTimers(S32 rez_status)
{
// State machine for rezzed status. Statuses are -1 on startup, 0
// = cloud, 1 = gray, 2 = downloading, 3 = full.
// Purpose is to collect time data for each it takes avatar to reach
// various loading landmarks: gray, textured (partial), textured fully.
S32 rez_status = getRezzedStatus();
if (rez_status != mLastRezzedStatus)
{
LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL;
@ -8661,8 +8663,13 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse
// returns true if the value has changed.
BOOL LLVOAvatar::updateIsFullyLoaded()
{
const bool loading = getIsCloud();
updateRezzedStatusTimers();
S32 rez_status = getRezzedStatus();
bool loading = getIsCloud();
if (mFirstFullyVisible && !mIsControlAvatar && rez_status < 3)
{
loading = ((rez_status < 2) || !isFullyBaked());
}
updateRezzedStatusTimers(rez_status);
updateRuthTimer(loading);
return processFullyLoadedChange(loading);
}
@ -8698,13 +8705,22 @@ void LLVOAvatar::updateRuthTimer(bool loading)
BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
{
// we wait a little bit before giving the all clear,
// to let textures settle down
const F32 PAUSE = 1.f;
// We wait a little bit before giving the 'all clear', to let things to
// settle down (models to snap into place, textures to get first packets)
const F32 LOADED_DELAY = 1.f;
const F32 FIRST_USE_DELAY = 3.f;
if (loading)
mFullyLoadedTimer.reset();
mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE);
if (mFirstFullyVisible)
{
mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > FIRST_USE_DELAY);
}
else
{
mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > LOADED_DELAY);
}
if (!mPreviousFullyLoaded && !loading && mFullyLoaded)
{

View File

@ -364,7 +364,7 @@ public:
BOOL isFullyTextured() const;
BOOL hasGray() const;
S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded.
void updateRezzedStatusTimers();
void updateRezzedStatusTimers(S32 status);
S32 mLastRezzedStatus;

View File

@ -1335,7 +1335,7 @@ void LLWorldMapView::drawAvatar(F32 x_pixels,
{
const F32 HEIGHT_THRESHOLD = 7.f;
LLUIImagePtr dot_image = sAvatarLevelImage;
if (unknown_relative_z)
if (unknown_relative_z && llabs(relative_z) > HEIGHT_THRESHOLD)
{
dot_image = sAvatarUnknownImage;
}