From 69508cb27bc6281d5bab1ab33c0790c4e337e58a Mon Sep 17 00:00:00 2001 From: Ansariel Date: Fri, 3 Feb 2012 15:05:00 +0100 Subject: [PATCH] * Proper fix of detecting avatars at unknown height after CoarseLocationUpdate update * Reverted proposed change of LLWorld::getAvatars() as part of STORM-1793, because it breaks stuff --- indra/newview/llnetmap.cpp | 64 ++++++++++++++++--------------- indra/newview/llpanelpeople.cpp | 2 +- indra/newview/llworld.cpp | 68 +++++++++++++++++++++++---------- indra/newview/llworld.h | 2 + 4 files changed, 85 insertions(+), 51 deletions(-) diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 5b3eb6a7b2..61ed2e7ba1 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -386,7 +386,7 @@ void LLNetMap::draw() // Draw avatars for (U32 i = 0; i < avatar_ids.size(); i++) { - //pos_map = globalPosToView(positions[i]); // Do this later after advanced height check + pos_map = globalPosToView(positions[i]); LLUUID uuid = avatar_ids[i]; // bool show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL); @@ -397,11 +397,26 @@ void LLNetMap::draw() LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color; - // Also check for legacy unknown height reported as height = 0m + // Check for unknown Z-offset => AVATAR_UNKNOWN_Z_OFFSET //unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z && // camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z; - unknown_relative_z = (positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z && - camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z) || (positions[i].mdV[VZ] == 0.f); + unknown_relative_z = false; + if (positions[i].mdV[VZ] == AVATAR_UNKNOWN_Z_OFFSET) + { + if (camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z) + { + // No exact data and cam >=1020 => we don't know if + // other avatar is above or below us => unknown + unknown_relative_z = true; + } + else + { + // No exact data but cam is below 1020 => other avatar + // is definitely above us => bump Z-offset to F32_MAX + // so we get the up chevron + pos_map.mV[VZ] = F32_MAX; + } + } // // Colorize muted avatars and Lindens @@ -411,19 +426,6 @@ void LLNetMap::draw() if (muteListInstance->isMuted(uuid)) color = map_avatar_muted_color; else if (gCacheName->getFullName(uuid, fullName) && muteListInstance->isLinden(fullName)) color = map_avatar_linden_color; - // Try to workaround 1020m bug by using - // the viewer object for the avatar. - if (unknown_relative_z) - { - LLViewerObject* viewerObject = gObjectList.findObject(uuid); - if (viewerObject) - { - positions[i].mdV[VZ] = viewerObject->getPositionGlobal().mdV[VZ]; - unknown_relative_z = false; - } - } - pos_map = globalPosToView(positions[i]); - // Mark Avatars with special colors - Ansariel if (LLNetMap::sAvatarMarksMap.find(uuid) != LLNetMap::sAvatarMarksMap.end()) { @@ -783,24 +785,26 @@ BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id) LLVector3d delta = otherPosition - myPosition; F32 distance = (F32)delta.magVec(); - // If avatar is >1020, the value for Z is returned as 0 (legacy) or 1020 (new) - bool isHigher1020mBug = (otherPosition[VZ] == COARSEUPDATE_MAX_Z || otherPosition[VZ] == 0.0); + // If avatar is >=1020, the value for Z might be returned as AVATAR_UNKNOWN_Z_OFFSET + bool isHigher1020mBug = (otherPosition[VZ] == AVATAR_UNKNOWN_Z_OFFSET); // Ansariel: Try to get distance from the nearby people panel - // aka radar. This usually contains better data, - // especially when above 1020m. - LLPanel* panel_people = LLSideTray::getInstance()->getPanel("panel_people"); - if (panel_people != NULL) + // aka radar when above 1020m. + if (isHigher1020mBug) { - LLAvatarListItem* avatar_list_item = ((LLPanelPeople*)panel_people)->getNearbyList()->getAvatarListItem(avatar_id); - if (avatar_list_item != NULL) + LLPanel* panel_people = LLSideTray::getInstance()->getPanel("panel_people"); + if (panel_people != NULL) { - F32 radar_distance = avatar_list_item->getRange(); - - if (isHigher1020mBug && radar_distance > -1.f) + LLAvatarListItem* avatar_list_item = ((LLPanelPeople*)panel_people)->getNearbyList()->getAvatarListItem(avatar_id); + if (avatar_list_item != NULL) { - distance = radar_distance; - isHigher1020mBug = false; + F32 radar_distance = avatar_list_item->getRange(); + + if (radar_distance > -1.f) + { + distance = radar_distance; + isHigher1020mBug = false; + } } } } diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 410993a7a2..7f2ed1ddd1 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -984,7 +984,7 @@ void LLPanelPeople::updateNearbyList() av->setAvatarName(avName); // maintain compatibility with underlying list, deprecated U32 lastZOffsetTime = av->getLastZOffsetTime(); F32 avZOffset = av->getZOffset(); - if (avPos[VZ] < 0.1 || avPos[VZ] == 1020.f) // if our official z position is 0.0 (legacy) or 1020 (new), we need a correction. + if (avPos[VZ] == AVATAR_UNKNOWN_Z_OFFSET) // if our official z position is AVATAR_UNKNOWN_Z_OFFSET, we need a correction. { // set correction if we have it if (avZOffset > 0.1) diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index ff5855c939..78e5e9ba2e 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1213,24 +1213,35 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector* positi { positions->clear(); } - // get the list of avatars from the character list first, so distances are correct - // when agent is above 1020m and other avatars are nearby - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter; - LLVector3d pos_global = pVOAvatar->getPositionGlobal(); - LLUUID uuid = pVOAvatar->getID(); - if( !pVOAvatar->isDead() && - !pVOAvatar->isSelf() && - !uuid.isNull() && - dist_vec_squared(pos_global, relative_to) <= radius_squared && - positions != NULL && - avatar_ids != NULL) - { - positions->push_back(pos_global); - avatar_ids->push_back(uuid); - } + // get the list of avatars from the character list first, so distances are correct + // when agent is above 1020m and other avatars are nearby + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + // Watch out for a potential merge of STORM-1793! + // avatar_ids and positions MUST be checked + // INDEPENDENTLY!!! Things rely on being able to + // pass either one as NULL!!! + LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter; + if(!pVOAvatar->isDead() && !pVOAvatar->isSelf()) + { + LLUUID uuid = pVOAvatar->getID(); + if(!uuid.isNull()) + { + LLVector3d pos_global = pVOAvatar->getPositionGlobal(); + if(dist_vec_squared(pos_global, relative_to) <= radius_squared) + { + if(positions != NULL) + { + positions->push_back(pos_global); + } + if(avatar_ids !=NULL) + { + avatar_ids->push_back(uuid); + } + } + } + } } // region avatars added for situations where radius is greater than RenderFarClip for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); @@ -1241,7 +1252,11 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector* positi S32 count = regionp->mMapAvatars.count(); for (S32 i = 0; i < count; i++) { - LLVector3d pos_global = unpackLocalToGlobalPosition(regionp->mMapAvatars.get(i), origin_global); + // + //LLVector3d pos_global = unpackLocalToGlobalPosition(regionp->mMapAvatars.get(i), origin_global); + U32 compact_local = regionp->mMapAvatars.get(i); + LLVector3d pos_global = unpackLocalToGlobalPosition(compact_local, origin_global); + // if(dist_vec_squared(pos_global, relative_to) <= radius_squared) { LLUUID uuid = regionp->mMapAvatarIDs.get(i); @@ -1250,9 +1265,22 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector* positi { if(positions != NULL) { + // Explictly return AVATAR_UNKNOWN_Z_OFFSET + // if height of avatar is unknown so we + // can take measures. If we wouldn't do + // this, we won't be able to distinguish + // if height is unknown or not if 1020 + // is returned for Z-offset. + U32 coarse_location_z_offset = (compact_local & 0xFFU); + if (coarse_location_z_offset == 255 || coarse_location_z_offset == 0) + { + pos_global.mdV[VZ] = AVATAR_UNKNOWN_Z_OFFSET; + } + // + positions->push_back(pos_global); - avatar_ids->push_back(uuid); } + avatar_ids->push_back(uuid); } } } diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 7a0bfe5078..c7aaa3e6ce 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -55,6 +55,8 @@ class LLCloudPuff; class LLCloudGroup; class LLVOAvatar; +const F32 AVATAR_UNKNOWN_Z_OFFSET = -1.f; // Const value for avatars at unknown height + // LLWorld maintains a stack of unused viewer_regions and an array of pointers to viewer regions // as simulators are connected to, viewer_regions are popped off the stack and connected as required // as simulators are removed, they are pushed back onto the stack