summaryrefslogtreecommitdiff
path: root/indra/newview/llvoavatar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvoavatar.cpp')
-rw-r--r--indra/newview/llvoavatar.cpp377
1 files changed, 256 insertions, 121 deletions
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index c31714de5a..8738ad7687 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -38,6 +38,7 @@
#include <ctype.h>
#include "llaudioengine.h"
+#include "llcachename.h"
#include "noise.h"
#include "sound_ids.h"
@@ -45,8 +46,10 @@
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "llanimationstates.h"
+#include "llavatarnamecache.h"
#include "llavatarpropertiesprocessor.h"
#include "llviewercontrol.h"
+#include "llcallingcard.h" // IDEVO for LLAvatarTracker
#include "lldrawpoolavatar.h"
#include "lldriverparam.h"
#include "lleditingmotion.h"
@@ -55,6 +58,8 @@
#include "llheadrotmotion.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
+#include "llhudnametag.h"
+#include "llhudtext.h" // for mText/mDebugText
#include "llkeyframefallmotion.h"
#include "llkeyframestandmotion.h"
#include "llkeyframewalkmotion.h"
@@ -653,12 +658,14 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mAppearanceAnimating(FALSE),
mNameString(),
mTitle(),
- mNameAway(FALSE),
- mNameBusy(FALSE),
- mNameMute(FALSE),
+ mNameAway(false),
+ mNameBusy(false),
+ mNameMute(false),
+ mNameAppearance(false),
+ mNameFriend(false),
+ mNameAlpha(0.f),
mRenderGroupTitles(sRenderGroupTitles),
- mNameAppearance(FALSE),
- mNameCloud(FALSE),
+ mNameCloud(false),
mFirstTEMessageReceived( FALSE ),
mFirstAppearanceMessageReceived( FALSE ),
mCulled( FALSE ),
@@ -2772,8 +2779,18 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
&& gSavedSettings.getS32("AvatarNameTagMode") ));
}
- if ( render_name )
+ if ( !render_name )
{
+ if (mNameText)
+ {
+ // ...clean up old name tag
+ mNameText->markDead();
+ mNameText = NULL;
+ sNumVisibleChatBubbles--;
+ }
+ return;
+ }
+
BOOL new_name = FALSE;
if (visible_chat != mVisibleChat)
{
@@ -2789,7 +2806,6 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
// First Calculate Alpha
// If alpha > 0, create mNameText if necessary, otherwise delete it
- {
F32 alpha = 0.f;
if (mAppAngle > 5.f)
{
@@ -2810,66 +2826,62 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
alpha = (mAppAngle-2.f)/3.f;
}
- if (alpha > 0.f)
+ if (alpha <= 0.f)
{
+ if (mNameText)
+ {
+ mNameText->markDead();
+ mNameText = NULL;
+ sNumVisibleChatBubbles--;
+ }
+ return;
+ }
+
if (!mNameText)
{
- mNameText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
- mNameText->setMass(10.f);
+ mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
+ LLHUDObject::LL_HUD_NAME_TAG) );
+ //mNameText->setMass(10.f);
mNameText->setSourceObject(this);
- mNameText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
+ mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
mNameText->setVisibleOffScreen(TRUE);
mNameText->setMaxLines(11);
mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
- mNameText->setUseBubble(TRUE);
sNumVisibleChatBubbles++;
new_name = TRUE;
}
- LLColor4 avatar_name_color = LLUIColorTable::instance().getColor( "AvatarNameColor" );
- avatar_name_color.setAlpha(alpha);
- mNameText->setColor(avatar_name_color);
+ LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);
+ mNameText->setPositionAgent(name_position);
- LLQuaternion root_rot = mRoot.getWorldRotation();
- mNameText->setUsePixelSize(TRUE);
- LLVector3 pixel_right_vec;
- LLVector3 pixel_up_vec;
- LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
- LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
- camera_to_av.normalize();
- LLVector3 local_camera_at = camera_to_av * ~root_rot;
- LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
- local_camera_up.normalize();
- local_camera_up = local_camera_up * ~root_rot;
+ idleUpdateNameTagText(new_name);
- local_camera_up.scaleVec(mBodySize * 0.5f);
- local_camera_at.scaleVec(mBodySize * 0.5f);
+ idleUpdateNameTagAlpha(new_name, alpha);
+}
- LLVector3 name_position = mRoot.getWorldPosition() +
- (local_camera_up * root_rot) -
- (projected_vec(local_camera_at * root_rot, camera_to_av));
- name_position += pixel_up_vec * 15.f;
- mNameText->setPositionAgent(name_position);
- }
- else if (mNameText)
+void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
{
- mNameText->markDead();
- mNameText = NULL;
- sNumVisibleChatBubbles--;
- }
- }
-
LLNameValue *title = getNVPair("Title");
LLNameValue* firstname = getNVPair("FirstName");
LLNameValue* lastname = getNVPair("LastName");
- if (mNameText.notNull() && firstname && lastname)
+ // Avatars must have a first and last name
+ if (!firstname || !lastname) return;
+
+ bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end();
+ bool is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end();
+ bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
+ bool is_muted;
+ if (isSelf())
+ {
+ is_muted = false;
+ }
+ else
{
- const BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end();
- const BOOL is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end();
- const BOOL is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
- const BOOL is_muted = isSelf() ? FALSE : LLMuteList::getInstance()->isMuted(getID());
- const BOOL is_cloud = getIsCloud();
+ is_muted = LLMuteList::getInstance()->isMuted(getID());
+ }
+ bool is_friend = LLAvatarTracker::instance().isBuddy(getID());
+ bool is_cloud = getIsCloud();
if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
{
@@ -2894,105 +2906,125 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
}
}
- if (mNameString.empty() ||
- new_name ||
- (!title && !mTitle.empty()) ||
- (title && mTitle != title->getString()) ||
- (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute)
+ // Rebuild name tag if state change detected
+ if (mNameString.empty()
+ || new_name
+ || (!title && !mTitle.empty())
+ || (title && mTitle != title->getString())
+ || is_away != mNameAway
+ || is_busy != mNameBusy
+ || is_muted != mNameMute
|| is_appearance != mNameAppearance
- || is_cloud != mNameCloud
- )
- {
- std::string line;
- if (!sRenderGroupTitles)
- {
- // If all group titles are turned off, stack first name
- // on a line above last name
- line += firstname->getString();
- line += "\n";
- }
- else if (title && title->getString() && title->getString()[0] != '\0')
+ || is_friend != mNameFriend
+ || is_cloud != mNameCloud)
{
- line += title->getString();
- LLStringFn::replace_ascii_controlchars(line,LL_UNKNOWN_CHAR);
- line += "\n";
- line += firstname->getString();
- }
- else
- {
- line += firstname->getString();
- }
+ LLColor4 name_tag_color = getNameTagColor(is_friend);
- line += " ";
- line += lastname->getString();
- BOOL need_comma = FALSE;
+ clearNameTag();
- if (is_away || is_muted || is_busy)
+ if (is_away || is_muted || is_busy || is_appearance)
{
- line += " (";
+ std::string line;
if (is_away)
{
line += LLTrans::getString("AvatarAway");
- need_comma = TRUE;
+ line += ", ";
}
if (is_busy)
{
- if (need_comma)
+ line += LLTrans::getString("AvatarBusy");
+ line += ", ";
+ }
+ if (is_muted)
{
+ line += LLTrans::getString("AvatarMuted");
line += ", ";
}
- line += LLTrans::getString("AvatarBusy");
- need_comma = TRUE;
+ if (is_appearance)
+ {
+ line += LLTrans::getString("AvatarEditingAppearance");
+ line += ", ";
}
- if (is_muted)
+ if (is_cloud)
{
- if (need_comma)
+ line += LLTrans::getString("LoadingData");
+ line += ", ";
+ }
+ // trim last ", "
+ line.resize( line.length() - 2 );
+ addNameTagLine(line, name_tag_color, LLFontGL::NORMAL,
+ LLFontGL::getFontSansSerifSmall());
+ }
+
+ if (sRenderGroupTitles
+ && title && title->getString() && title->getString()[0] != '\0')
{
- line += ", ";
+ std::string title_str = title->getString();
+ LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
+ addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
+ LLFontGL::getFontSansSerifSmall());
}
- line += LLTrans::getString("AvatarMuted");
- need_comma = TRUE;
+
+ static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
+ static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
+
+ if (LLAvatarNameCache::useDisplayNames())
+ {
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get(getID(), &av_name))
+ {
+ // ...call this function back when the name arrives
+ // and force a rebuild
+ LLAvatarNameCache::get(getID(),
+ boost::bind(&LLVOAvatar::clearNameTag, this));
}
- line += ")";
+
+ // Might be blank if name not available yet, that's OK
+ if (show_display_names)
+ {
+ addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
+ LLFontGL::getFontSansSerif());
}
- if (is_cloud)
+ // Suppress SLID display if display name matches exactly (ugh)
+ if (show_usernames && !av_name.mIsDisplayNameDefault)
{
- line += "\n";
- line += "(" + LLTrans::getString("LoadingData") + ")";
+ // *HACK: Desaturate the color
+ LLColor4 username_color = name_tag_color * 0.83f;
+ addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
+ LLFontGL::getFontSansSerifSmall());
+ }
}
- else if (is_appearance)
+ else
{
- line += "\n";
- line += LLTrans::getString("AvatarEditingAppearance");
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
+ std::string full_name =
+ LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
+ addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
}
+
mNameAway = is_away;
mNameBusy = is_busy;
mNameMute = is_muted;
mNameAppearance = is_appearance;
+ mNameFriend = is_friend;
mNameCloud = is_cloud;
mTitle = title ? title->getString() : "";
LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
- mNameString = utf8str_to_wstring(line);
new_name = TRUE;
}
- if (visible_chat)
+ if (mVisibleChat)
{
- mNameText->setDropShadow(TRUE);
mNameText->setFont(LLFontGL::getFontSansSerif());
- mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_LEFT);
+ mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
- if (new_name)
- {
- mNameText->setLabel(mNameString);
- }
char line[MAX_STRING]; /* Flawfinder: ignore */
line[0] = '\0';
std::deque<LLChat>::iterator chat_iter = mChats.begin();
mNameText->clearString();
- LLColor4 new_chat = LLUIColorTable::instance().getColor( "AvatarNameColor" );
+ LLColor4 new_chat = LLUIColorTable::instance().getColor( "NameTagChat" );
LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)
@@ -3019,17 +3051,17 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
if (chat_fade_amt < 1.f)
{
F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
- mNameText->addLine(utf8str_to_wstring(chat_iter->mText), lerp(new_chat, normal_chat, u), style);
+ mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
}
else if (chat_fade_amt < 2.f)
{
F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
- mNameText->addLine(utf8str_to_wstring(chat_iter->mText), lerp(normal_chat, old_chat, u), style);
+ mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
}
else if (chat_fade_amt < 3.f)
{
// *NOTE: only remove lines down to minimum number
- mNameText->addLine(utf8str_to_wstring(chat_iter->mText), old_chat, style);
+ mNameText->addLine(chat_iter->mText, old_chat, style);
}
}
mNameText->setVisibleOffScreen(TRUE);
@@ -3054,24 +3086,129 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
}
else
{
- mNameText->setFont(LLFontGL::getFontSansSerif());
- mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_CENTER);
+ // ...not using chat bubbles, just names
+ mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
mNameText->setVisibleOffScreen(FALSE);
- if (new_name)
+ }
+}
+
+void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font)
+{
+ llassert(mNameText);
+ if (mVisibleChat)
+ {
+ mNameText->addLabel(line);
+ }
+ else
+ {
+ mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font);
+ }
+ mNameString += line;
+ mNameString += '\n';
+}
+
+void LLVOAvatar::clearNameTag()
+{
+ mNameString.clear();
+ if (mNameText)
{
mNameText->setLabel("");
- mNameText->setString(mNameString);
+ mNameText->setString( "" );
+ }
+}
+
+//static
+void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id)
+{
+ LLViewerObject* obj = gObjectList.findObject(agent_id);
+ if (!obj) return;
+
+ LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(obj);
+ if (!avatar) return;
+
+ avatar->clearNameTag();
+}
+
+//static
+void LLVOAvatar::invalidateNameTags()
+{
+ std::vector<LLCharacter*>::iterator it = LLCharacter::sInstances.begin();
+ for ( ; it != LLCharacter::sInstances.end(); ++it)
+ {
+ LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*it);
+ if (!avatar) continue;
+ if (avatar->isDead()) continue;
+
+ avatar->clearNameTag();
}
}
+
+// Compute name tag position during idle update
+LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
+{
+ LLQuaternion root_rot = mRoot.getWorldRotation();
+ LLVector3 pixel_right_vec;
+ LLVector3 pixel_up_vec;
+ LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
+ LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
+ camera_to_av.normalize();
+ LLVector3 local_camera_at = camera_to_av * ~root_rot;
+ LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
+ local_camera_up.normalize();
+ local_camera_up = local_camera_up * ~root_rot;
+
+ local_camera_up.scaleVec(mBodySize * 0.5f);
+ local_camera_at.scaleVec(mBodySize * 0.5f);
+
+ LLVector3 name_position = mRoot.getWorldPosition() +
+ (local_camera_up * root_rot) -
+ (projected_vec(local_camera_at * root_rot, camera_to_av));
+ name_position += pixel_up_vec * 15.f;
+ return name_position;
+ }
+
+void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
+{
+ llassert(mNameText);
+
+ if (new_name
+ || alpha != mNameAlpha)
+ {
+ mNameText->setAlpha(alpha);
+ mNameAlpha = alpha;
+ }
+}
+
+LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
+{
+ static LLUICachedControl<bool> show_friends("NameTagShowFriends");
+ const char* color_name;
+ if (show_friends && is_friend)
+ {
+ color_name = "NameTagFriend";
+ }
+ else if (LLAvatarNameCache::useDisplayNames())
+ {
+ // ...color based on whether username "matches" a computed display
+ // name
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(getID(), &av_name)
+ && av_name.mIsDisplayNameDefault)
+ {
+ color_name = "NameTagMatch";
}
+ else
+ {
+ color_name = "NameTagMismatch";
}
- else if (mNameText)
+ }
+ else
{
- mNameText->markDead();
- mNameText = NULL;
- sNumVisibleChatBubbles--;
+ // ...not using display names
+ color_name = "NameTagLegacy";
}
+ return LLUIColorTable::getInstance()->getColor( color_name );
}
void LLVOAvatar::idleUpdateBelowWater()
@@ -6748,7 +6885,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
{
releaseComponentTextures();
}
-
+
// parse visual params
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
@@ -6843,9 +6980,9 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
llinfos << "Re-requesting AvatarAppearance for object: " << getID() << llendl;
LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
mRuthTimer.reset();
- }
- else
- {
+ }
+ else
+ {
llinfos << "That's okay, we already have a non-default shape for object: " << getID() << llendl;
// we don't really care.
}
@@ -7737,9 +7874,7 @@ std::string LLVOAvatar::getFullname() const
LLNameValue* last = getNVPair("LastName");
if (first && last)
{
- name += first->getString();
- name += " ";
- name += last->getString();
+ name = LLCacheName::buildFullName( first->getString(), last->getString() );
}
return name;