summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerobjectlist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewerobjectlist.cpp')
-rw-r--r--indra/newview/llviewerobjectlist.cpp515
1 files changed, 302 insertions, 213 deletions
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 8d1867cc31..b597e6148e 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -2,30 +2,25 @@
* @file llviewerobjectlist.cpp
* @brief Implementation of LLViewerObjectList class.
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,7 +31,8 @@
#include "message.h"
#include "timing.h"
#include "llfasttimer.h"
-#include "llglimmediate.h"
+#include "llrender.h"
+#include "llwindow.h" // decBusyCount()
#include "llviewercontrol.h"
#include "llface.h"
@@ -45,12 +41,13 @@
#include "llviewerwindow.h"
#include "llnetmap.h"
#include "llagent.h"
+#include "llagentcamera.h"
#include "pipeline.h"
#include "llspatialpartition.h"
-#include "llhoverview.h"
+#include "lltooltip.h"
#include "llworld.h"
#include "llstring.h"
-#include "llhudtext.h"
+#include "llhudnametag.h"
#include "lldrawable.h"
#include "xform.h"
#include "llsky.h"
@@ -59,11 +56,12 @@
#include "llresmgr.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
+#include "llvoavatarself.h"
#include "lltoolmgr.h"
#include "lltoolpie.h"
#include "llkeyboard.h"
#include "u64.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "lldatapacker.h"
#ifdef LL_STANDALONE
#include <zlib.h>
@@ -90,7 +88,7 @@ extern LLPipeline gPipeline;
// Statics for object lookup tables.
U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check.
-LLMap<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
+std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID;
LLViewerObjectList::LLViewerObjectList()
@@ -163,15 +161,37 @@ U64 LLViewerObjectList::getIndex(const U32 local_id,
BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object)
{
- U32 local_id = object.mLocalID;
- LLHost region_host = object.getRegion()->getHost();
- U32 ip = region_host.getAddress();
- U32 port = region_host.getPort();
- U64 ipport = (((U64)ip) << 32) | (U64)port;
- U32 index = sIPAndPortToIndex[ipport];
-
- U64 indexid = (((U64)index) << 32) | (U64)local_id;
- return sIndexAndLocalIDToUUID.erase(indexid) > 0 ? TRUE : FALSE;
+ if(object.getRegion())
+ {
+ U32 local_id = object.mLocalID;
+ LLHost region_host = object.getRegion()->getHost();
+ U32 ip = region_host.getAddress();
+ U32 port = region_host.getPort();
+ U64 ipport = (((U64)ip) << 32) | (U64)port;
+ U32 index = sIPAndPortToIndex[ipport];
+
+ // llinfos << "Removing object from table, local ID " << local_id << ", ip " << ip << ":" << port << llendl;
+
+ U64 indexid = (((U64)index) << 32) | (U64)local_id;
+
+ std::map<U64, LLUUID>::iterator iter = sIndexAndLocalIDToUUID.find(indexid);
+ if (iter == sIndexAndLocalIDToUUID.end())
+ {
+ return FALSE;
+ }
+
+ // Found existing entry
+ if (iter->second == object.getID())
+ { // Full UUIDs match, so remove the entry
+ sIndexAndLocalIDToUUID.erase(iter);
+ return TRUE;
+ }
+ // UUIDs did not match - this would zap a valid entry, so don't erase it
+ //llinfos << "Tried to erase entry where id in table ("
+ // << iter->second << ") did not match object " << object.getID() << llendl;
+ }
+
+ return FALSE ;
}
void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
@@ -192,6 +212,9 @@ void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
U64 indexid = (((U64)index) << 32) | (U64)local_id;
sIndexAndLocalIDToUUID[indexid] = id;
+
+ //llinfos << "Adding object to table, full ID " << id
+ // << ", local ID " << local_id << ", ip " << ip << ":" << port << llendl;
}
S32 gFullObjectUpdates = 0;
@@ -204,6 +227,7 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
LLDataPacker* dpp,
BOOL just_created)
{
+ LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE_CORE);
LLMessageSystem* msg = gMessageSystem;
// ignore returned flags
@@ -235,28 +259,31 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
&& update_type != OUT_TERSE_IMPROVED
&& objectp->mCreateSelected)
{
- if ( gToolMgr->getCurrentTool() != gToolPie )
+ if ( LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() )
{
- //llinfos << "DEBUG selecting " << objectp->mID << " "
- // << objectp->mLocalID << llendl;
- gSelectMgr->selectObjectAndFamily(objectp);
+ // llinfos << "DEBUG selecting " << objectp->mID << " "
+ // << objectp->mLocalID << llendl;
+ LLSelectMgr::getInstance()->selectObjectAndFamily(objectp);
dialog_refresh_all();
}
objectp->mCreateSelected = false;
gViewerWindow->getWindow()->decBusyCount();
- gViewerWindow->getWindow()->setCursor( UI_CURSOR_ARROW );
+ gViewerWindow->setCursor( UI_CURSOR_ARROW );
}
}
+static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
+
void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
void **user_data,
const EObjectUpdateType update_type,
bool cached, bool compressed)
{
- LLFastTimer t(LLFastTimer::FTM_PROCESS_OBJECTS);
+ LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE);
+ LLFastTimer t(FTM_PROCESS_OBJECTS);
- LLVector3d camera_global = gAgent.getCameraPositionGlobal();
+ LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
LLViewerObject *objectp;
S32 num_objects;
U32 local_id;
@@ -282,7 +309,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
{
size = mesgsys->getReceiveSize();
}
-// llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+ // llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
}
else
{
@@ -296,17 +323,17 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
size = mesgsys->getReceiveSize();
}
-// llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+ // llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
gFullObjectUpdates += num_objects;
}
U64 region_handle;
mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
- LLViewerRegion *regionp = gWorldPointer->getRegionFromHandle(region_handle);
+ LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
if (!regionp)
{
- llwarns << "Object update from unknown region!" << llendl;
+ llwarns << "Object update from unknown region! " << region_handle << llendl;
return;
}
@@ -345,7 +372,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
U8 compbuffer[2048];
S32 uncompressed_length = 2048;
S32 compressed_length;
-
compressed_dp.reset();
U32 flags = 0;
@@ -386,7 +412,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
gMessageSystem->getSenderPort());
if (fullid.isNull())
{
- //llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << llendl;
+ // llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << ":" << gMessageSystem->getSenderPort() << llendl;
mNumUnknownUpdates++;
}
}
@@ -400,7 +426,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
gMessageSystem->getSenderPort());
if (fullid.isNull())
{
- //llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << llendl;
+ // llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << llendl;
mNumUnknownUpdates++;
}
}
@@ -408,19 +434,42 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
{
mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
- // llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl;
+ // llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl;
}
objectp = findObject(fullid);
// This looks like it will break if the local_id of the object doesn't change
// upon boundary crossing, but we check for region id matching later...
- if (objectp && (objectp->mLocalID != local_id))
+ // Reset object local id and region pointer if things have changed
+ if (objectp &&
+ ((objectp->mLocalID != local_id) ||
+ (objectp->getRegion() != regionp)))
{
+ //if (objectp->getRegion())
+ //{
+ // llinfos << "Local ID change: Removing object from table, local ID " << objectp->mLocalID
+ // << ", id from message " << local_id << ", from "
+ // << LLHost(objectp->getRegion()->getHost().getAddress(), objectp->getRegion()->getHost().getPort())
+ // << ", full id " << fullid
+ // << ", objects id " << objectp->getID()
+ // << ", regionp " << (U32) regionp << ", object region " << (U32) objectp->getRegion()
+ // << llendl;
+ //}
removeFromLocalIDTable(*objectp);
setUUIDAndLocal(fullid,
local_id,
gMessageSystem->getSenderIP(),
gMessageSystem->getSenderPort());
+
+ if (objectp->mLocalID != local_id)
+ { // Update local ID in object with the one sent from the region
+ objectp->mLocalID = local_id;
+ }
+
+ if (objectp->getRegion() != regionp)
+ { // Object changed region, so update it
+ objectp->updateRegion(regionp); // for LLVOAvatar
+ }
}
if (!objectp)
@@ -429,7 +478,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
{
if (update_type == OUT_TERSE_IMPROVED)
{
- // llinfos << "terse update for an unknown object:" << fullid << llendl;
+ // llinfos << "terse update for an unknown object:" << fullid << llendl;
continue;
}
}
@@ -440,7 +489,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
{
if (update_type != OUT_FULL)
{
-// llinfos << "terse update for an unknown object:" << fullid << llendl;
+ // llinfos << "terse update for an unknown object:" << fullid << llendl;
continue;
}
@@ -450,7 +499,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if (mDeadObjects.find(fullid) != mDeadObjects.end())
{
mNumDeadObjectUpdates++;
- //llinfos << "update for a dead object:" << fullid << llendl;
+ // llinfos << "update for a dead object:" << fullid << llendl;
continue;
}
#endif
@@ -463,20 +512,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
justCreated = TRUE;
mNumNewObjects++;
}
- else
- {
- if (objectp->getRegion() != regionp)
- {
- // Object has changed region! Update lookup tables, set region pointer.
- removeFromLocalIDTable(*objectp);
- setUUIDAndLocal(fullid,
- local_id,
- gMessageSystem->getSenderIP(),
- gMessageSystem->getSenderPort());
- objectp->setRegion(regionp);
- }
- objectp->updateRegion(regionp); // for LLVOAvatar
- }
if (objectp->isDead())
@@ -530,10 +565,9 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,
void LLViewerObjectList::dirtyAllObjectInventory()
{
- S32 count = mObjects.count();
- for(S32 i = 0; i < count; ++i)
+ for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
- mObjects[i]->dirtyInventory();
+ (*iter)->dirtyInventory();
}
}
@@ -546,14 +580,14 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
S32 num_updates, max_value;
if (NUM_BINS - 1 == mCurBin)
{
- num_updates = mObjects.count() - mCurLazyUpdateIndex;
- max_value = mObjects.count();
- gImageList.setUpdateStats(TRUE);
+ num_updates = (S32) mObjects.size() - mCurLazyUpdateIndex;
+ max_value = (S32) mObjects.size();
+ gTextureList.setUpdateStats(TRUE);
}
else
{
- num_updates = (mObjects.count() / NUM_BINS) + 1;
- max_value = llmin(mObjects.count(), mCurLazyUpdateIndex + num_updates);
+ num_updates = ((S32) mObjects.size() / NUM_BINS) + 1;
+ max_value = llmin((S32) mObjects.size(), mCurLazyUpdateIndex + num_updates);
}
@@ -562,15 +596,19 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
// Slam priorities for textures that we care about (hovered, selected, and focused)
// Hovered
// Assumes only one level deep of parenting
- objectp = gHoverView->getLastHoverObject();
- if (objectp)
+ LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
+ if (nodep)
{
- objectp->boostTexturePriority();
+ objectp = nodep->getObject();
+ if (objectp)
+ {
+ objectp->boostTexturePriority();
+ }
}
}
// Focused
- objectp = gAgent.getFocusObject();
+ objectp = gAgentCamera.getFocusObject();
if (objectp)
{
objectp->boostTexturePriority();
@@ -585,7 +623,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
return true;
}
} func;
- gSelectMgr->getSelection()->applyToRootObjects(&func);
+ LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);
// Iterate through some of the objects and lazy update their texture priorities
for (i = mCurLazyUpdateIndex; i < max_value; i++)
@@ -597,17 +635,17 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
// Update distance & gpw
objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area
- objectp->updateTextures(agent); // Update the image levels of textures for this object.
+ objectp->updateTextures(); // Update the image levels of textures for this object.
}
}
mCurLazyUpdateIndex = max_value;
- if (mCurLazyUpdateIndex == mObjects.count())
+ if (mCurLazyUpdateIndex == mObjects.size())
{
mCurLazyUpdateIndex = 0;
}
- mCurBin = (++mCurBin) % NUM_BINS;
+ mCurBin = (mCurBin + 1) % NUM_BINS;
LLVOAvatar::cullAvatarsByPixelArea();
}
@@ -649,20 +687,26 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
// Make a copy of the list in case something in idleUpdate() messes with it
std::vector<LLViewerObject*> idle_list;
- idle_list.reserve( mActiveObjects.size() );
+
+ static LLFastTimer::DeclareTimer idle_copy("Idle Copy");
- for (std::set<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
- active_iter != mActiveObjects.end(); active_iter++)
{
- objectp = *active_iter;
- if (objectp)
+ LLFastTimer t(idle_copy);
+ idle_list.reserve( mActiveObjects.size() );
+
+ for (std::set<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
+ active_iter != mActiveObjects.end(); active_iter++)
{
- idle_list.push_back( objectp );
- }
- else
- { // There shouldn't be any NULL pointers in the list, but they have caused
- // crashes before. This may be idleUpdate() messing with the list.
- llwarns << "LLViewerObjectList::update has a NULL objectp" << llendl;
+ objectp = *active_iter;
+ if (objectp)
+ {
+ idle_list.push_back( objectp );
+ }
+ else
+ { // There shouldn't be any NULL pointers in the list, but they have caused
+ // crashes before. This may be idleUpdate() messing with the list.
+ llwarns << "LLViewerObjectList::update has a NULL objectp" << llendl;
+ }
}
}
@@ -710,23 +754,23 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
// don't factor frames that were paused into the stats
if (! mWasPaused)
{
- gViewerStats->updateFrameStats(time_diff);
+ LLViewerStats::getInstance()->updateFrameStats(time_diff);
}
/*
// Debugging code for viewing orphans, and orphaned parents
LLUUID id;
- char id_str[UUID_STR_LENGTH + 20];
for (i = 0; i < mOrphanParents.count(); i++)
{
id = sIndexAndLocalIDToUUID[mOrphanParents[i]];
LLViewerObject *objectp = findObject(id);
if (objectp)
{
- sprintf(id_str, "Par: ");
- objectp->mID.toString(id_str + 5);
+ std::string id_str;
+ objectp->mID.toString(id_str);
+ std::string tmpstr = std::string("Par: ") + id_str;
addDebugBeacon(objectp->getPositionAgent(),
- id_str,
+ tmpstr,
LLColor4(1.f,0.f,0.f,1.f),
LLColor4(1.f,1.f,1.f,1.f));
}
@@ -739,20 +783,22 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
LLViewerObject *objectp = findObject(oi.mChildInfo);
if (objectp)
{
+ std::string id_str;
+ objectp->mID.toString(id_str);
+ std::string tmpstr;
if (objectp->getParent())
{
- sprintf(id_str, "ChP: ");
+ tmpstr = std::string("ChP: ") + id_str;
text_color = LLColor4(0.f, 1.f, 0.f, 1.f);
}
else
{
- sprintf(id_str, "ChNoP: ");
+ tmpstr = std::string("ChNoP: ") + id_str;
text_color = LLColor4(1.f, 0.f, 0.f, 1.f);
}
id = sIndexAndLocalIDToUUID[oi.mParentInfo];
- objectp->mID.toString(id_str + 8);
addDebugBeacon(objectp->getPositionAgent() + LLVector3(0.f, 0.f, -0.25f),
- id_str,
+ tmpstr,
LLColor4(0.25f,0.25f,0.25f,1.f),
text_color);
}
@@ -760,17 +806,17 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
}
*/
- mNumObjectsStat.addValue(mObjects.count());
- mNumActiveObjectsStat.addValue(num_active_objects);
- mNumSizeCulledStat.addValue(mNumSizeCulled);
- mNumVisCulledStat.addValue(mNumVisCulled);
+ LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size());
+ LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(num_active_objects);
+ LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled);
+ LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled);
}
void LLViewerObjectList::clearDebugText()
{
- for (S32 i = 0; i < mObjects.count(); i++)
+ for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
- mObjects[i]->setDebugText("");
+ (*iter)->setDebugText("");
}
}
@@ -790,6 +836,14 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
// Remove from object map so noone can look it up.
mUUIDObjectMap.erase(objectp->mID);
+
+ //if (objectp->getRegion())
+ //{
+ // llinfos << "cleanupReferences removing object from table, local ID " << objectp->mLocalID << ", ip "
+ // << objectp->getRegion()->getHost().getAddress() << ":"
+ // << objectp->getRegion()->getHost().getPort() << llendl;
+ //}
+
removeFromLocalIDTable(*objectp);
if (objectp->onActiveList())
@@ -801,7 +855,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
if (objectp->isOnMap())
{
- mMapObjects.removeObj(objectp);
+ removeFromMap(objectp);
}
// Don't clean up mObject references, these will be cleaned up more efficiently later!
@@ -820,13 +874,27 @@ void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
for (S32 i = 0; i < drawablep->getNumFaces(); i++)
{
- LLViewerObject* objectp = drawablep->getFace(i)->getViewerObject();
- mSelectPickList.erase(objectp);
+ LLFace* facep = drawablep->getFace(i) ;
+ if(facep)
+ {
+ LLViewerObject* objectp = facep->getViewerObject();
+ if(objectp)
+ {
+ mSelectPickList.erase(objectp);
+ }
+ }
}
}
BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
{
+ // Don't ever kill gAgentAvatarp, just force it to the agent's region
+ if (objectp == gAgentAvatarp)
+ {
+ objectp->setRegion(gAgent.getRegion());
+ return FALSE;
+ }
+
// When we're killing objects, all we do is mark them as dead.
// We clean up the dead objects later.
@@ -851,10 +919,10 @@ void LLViewerObjectList::killObjects(LLViewerRegion *regionp)
{
LLViewerObject *objectp;
- S32 i;
- for (i = 0; i < mObjects.count(); i++)
+
+ for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
- objectp = mObjects[i];
+ objectp = *iter;
if (objectp->mRegionp == regionp)
{
@@ -871,19 +939,19 @@ void LLViewerObjectList::killAllObjects()
// Used only on global destruction.
LLViewerObject *objectp;
- for (S32 i = 0; i < mObjects.count(); i++)
+ for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
- objectp = mObjects[i];
-
+ objectp = *iter;
killObject(objectp);
- llassert(objectp->isDead());
+ // Object must be dead, or it's the LLVOAvatarSelf which never dies.
+ llassert((objectp == gAgentAvatarp) || objectp->isDead());
}
cleanDeadObjects(FALSE);
if(!mObjects.empty())
{
- llwarns << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.count() << llendl;
+ llwarns << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.size() << llendl;
mObjects.clear();
}
@@ -896,7 +964,7 @@ void LLViewerObjectList::killAllObjects()
if (!mMapObjects.empty())
{
llwarns << "Some objects still on map object list!" << llendl;
- mActiveObjects.clear();
+ mMapObjects.clear();
}
}
@@ -908,16 +976,15 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
return;
}
- S32 i = 0;
S32 num_removed = 0;
LLViewerObject *objectp;
- while (i < mObjects.count())
+ for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); )
{
// Scan for all of the dead objects and remove any "global" references to them.
- objectp = mObjects[i];
+ objectp = *iter;
if (objectp->isDead())
{
- mObjects.remove(i);
+ iter = mObjects.erase(iter);
num_removed++;
if (num_removed == mNumDeadObjects)
@@ -928,8 +995,7 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
}
else
{
- // iterate, this isn't a dead object.
- i++;
+ ++iter;
}
}
@@ -979,12 +1045,11 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
}
LLViewerObject *objectp;
- S32 i;
- for (i = 0; i < mObjects.count(); i++)
+ for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
- objectp = getObject(i);
+ objectp = *iter;
// There could be dead objects on the object list, so don't update stuff if the object is dead.
- if (objectp)
+ if (!objectp->isDead())
{
objectp->updatePositionCaches();
@@ -996,26 +1061,27 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
}
gPipeline.shiftObjects(offset);
- gWorldp->shiftRegions(offset);
+ LLWorld::getInstance()->shiftRegions(offset);
}
void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap)
{
- LLColor4 above_water_color = gColors.getColor( "NetMapOtherOwnAboveWater" );
- LLColor4 below_water_color = gColors.getColor( "NetMapOtherOwnBelowWater" );
+ LLColor4 above_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnAboveWater" );
+ LLColor4 below_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnBelowWater" );
LLColor4 you_own_above_water_color =
- gColors.getColor( "NetMapYouOwnAboveWater" );
+ LLUIColorTable::instance().getColor( "NetMapYouOwnAboveWater" );
LLColor4 you_own_below_water_color =
- gColors.getColor( "NetMapYouOwnBelowWater" );
+ LLUIColorTable::instance().getColor( "NetMapYouOwnBelowWater" );
LLColor4 group_own_above_water_color =
- gColors.getColor( "NetMapGroupOwnAboveWater" );
+ LLUIColorTable::instance().getColor( "NetMapGroupOwnAboveWater" );
LLColor4 group_own_below_water_color =
- gColors.getColor( "NetMapGroupOwnBelowWater" );
+ LLUIColorTable::instance().getColor( "NetMapGroupOwnBelowWater" );
+ F32 max_radius = gSavedSettings.getF32("MiniMapPrimMaxRadius");
- for (S32 i = 0; i < mMapObjects.count(); i++)
+ for (vobj_list_t::iterator iter = mMapObjects.begin(); iter != mMapObjects.end(); ++iter)
{
- LLViewerObject* objectp = mMapObjects[i];
+ LLViewerObject* objectp = *iter;
if (!objectp->getRegion() || objectp->isOrphaned() || objectp->isAttachment())
{
continue;
@@ -1023,10 +1089,15 @@ void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap)
const LLVector3& scale = objectp->getScale();
const LLVector3d pos = objectp->getPositionGlobal();
const F64 water_height = F64( objectp->getRegion()->getWaterHeight() );
- // gWorldPointer->getWaterHeight();
+ // LLWorld::getInstance()->getWaterHeight();
F32 approx_radius = (scale.mV[VX] + scale.mV[VY]) * 0.5f * 0.5f * 1.3f; // 1.3 is a fudge
+ // Limit the size of megaprims so they don't blot out everything on the minimap.
+ // Attempting to draw very large megaprims also causes client lag.
+ // See DEV-17370 and DEV-29869/SNOW-79 for details.
+ approx_radius = llmin(approx_radius, max_radius);
+
LLColor4U color = above_water_color;
if( objectp->permYouOwner() )
{
@@ -1076,29 +1147,22 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 &center)
{
}
-
-U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parcel_wall, BOOL keep_pick_list)
+void LLViewerObjectList::generatePickList(LLCamera &camera)
{
- gRenderForSelect = TRUE;
-
- // LLTimer pick_timer;
- if (!keep_pick_list)
- {
LLViewerObject *objectp;
S32 i;
// Reset all of the GL names to zero.
- for (i = 0; i < mObjects.count(); i++)
+ for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
- objectp = mObjects[i];
- objectp->mGLName = 0;
+ (*iter)->mGLName = 0;
}
mSelectPickList.clear();
std::vector<LLDrawable*> pick_drawables;
- for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin();
- iter != gWorldp->getRegionList().end(); ++iter)
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
LLViewerRegion* region = *iter;
for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
@@ -1131,7 +1195,7 @@ U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parce
}
}
- LLHUDText::addPickable(mSelectPickList);
+ LLHUDNameTag::addPickable(mSelectPickList);
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
iter != LLCharacter::sInstances.end(); ++iter)
@@ -1147,26 +1211,31 @@ U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parce
}
// add all hud objects to pick list
- LLVOAvatar* avatarp = gAgent.getAvatarObject();
- if (avatarp)
+ if (isAgentAvatarValid())
{
- for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
- iter != avatarp->mAttachmentPoints.end(); )
+ for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
+ iter != gAgentAvatarp->mAttachmentPoints.end(); )
{
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachmentp = curiter->second;
- if (attachmentp->getIsHUDAttachment())
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (attachment->getIsHUDAttachment())
{
- LLViewerObject* objectp = attachmentp->getObject();
- if (objectp)
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- mSelectPickList.insert(objectp);
- for (U32 i = 0; i < objectp->mChildList.size(); i++)
+ if (LLViewerObject* attached_object = (*attachment_iter))
{
- LLViewerObject* childp = objectp->mChildList[i];
- if (childp)
+ mSelectPickList.insert(attached_object);
+ LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
{
- mSelectPickList.insert(childp);
+ LLViewerObject* childp = *iter;
+ if (childp)
+ {
+ mSelectPickList.insert(childp);
+ }
}
}
}
@@ -1197,27 +1266,35 @@ U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parce
}
LLHUDIcon::generatePickIDs(i * step, step);
-
- // At this point, we should only have live drawables/viewer objects
- gPipeline.renderForSelect(mSelectPickList);
- }
}
+}
+
+void LLViewerObjectList::renderPickList(const LLRect& screen_rect, BOOL pick_parcel_wall, BOOL render_transparent)
+{
+ gRenderForSelect = TRUE;
+
+ gPipeline.renderForSelect(mSelectPickList, render_transparent, screen_rect);
//
// Render pass for selected objects
//
- gGL.start();
+ gGL.color4f(1,1,1,1);
gViewerWindow->renderSelections( TRUE, pick_parcel_wall, FALSE );
- // render pickable ui elements, like names, etc.
- LLHUDObject::renderAllForSelect();
- gGL.stop();
+ //fix for DEV-19335. Don't pick hud objects when customizing avatar (camera mode doesn't play nice with nametags).
+ if (!gAgentCamera.cameraCustomizeAvatar())
+ {
+ // render pickable ui elements, like names, etc.
+ LLHUDObject::renderAllForSelect();
+ }
+
+ gGL.flush();
+ LLVertexBuffer::unbind();
gRenderForSelect = FALSE;
//llinfos << "Rendered " << count << " for select" << llendl;
//llinfos << "Took " << pick_timer.getElapsedTimeF32()*1000.f << "ms to pick" << llendl;
- return 0;
}
LLViewerObject *LLViewerObjectList::getSelectedObject(const U32 object_id)
@@ -1234,22 +1311,24 @@ LLViewerObject *LLViewerObjectList::getSelectedObject(const U32 object_id)
}
void LLViewerObjectList::addDebugBeacon(const LLVector3 &pos_agent,
- const LLString &string,
+ const std::string &string,
const LLColor4 &color,
const LLColor4 &text_color,
S32 line_width)
{
- LLDebugBeacon *beaconp = mDebugBeacons.reserve_block(1);
- beaconp->mPositionAgent = pos_agent;
- beaconp->mString = string;
- beaconp->mColor = color;
- beaconp->mTextColor = text_color;
- beaconp->mLineWidth = line_width;
+ LLDebugBeacon beacon;
+ beacon.mPositionAgent = pos_agent;
+ beacon.mString = string;
+ beacon.mColor = color;
+ beacon.mTextColor = text_color;
+ beacon.mLineWidth = line_width;
+
+ mDebugBeacons.push_back(beacon);
}
void LLViewerObjectList::resetObjectBeacons()
{
- mDebugBeacons.reset();
+ mDebugBeacons.clear();
}
LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp)
@@ -1267,7 +1346,7 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi
mUUIDObjectMap[fullid] = objectp;
- mObjects.put(objectp);
+ mObjects.push_back(objectp);
updateActive(objectp);
@@ -1275,12 +1354,13 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi
}
+static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,
const LLUUID &uuid, const U32 local_id, const LLHost &sender)
{
LLMemType mt(LLMemType::MTYPE_OBJECT);
- LLFastTimer t(LLFastTimer::FTM_CREATE_OBJECT);
+ LLFastTimer t(FTM_CREATE_OBJECT);
LLUUID fullid;
if (uuid == LLUUID::null)
@@ -1305,7 +1385,7 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe
gMessageSystem->getSenderIP(),
gMessageSystem->getSenderPort());
- mObjects.put(objectp);
+ mObjects.push_back(objectp);
updateActive(objectp);
@@ -1328,11 +1408,11 @@ LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCod
S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const
{
LLViewerObject *objectp;
- S32 i;
S32 num_refs = 0;
- for (i = 0; i < mObjects.count(); i++)
+
+ for (vobj_list_t::const_iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
- objectp = mObjects[i];
+ objectp = *iter;
if (objectp->mDrawable.notNull())
{
num_refs += objectp->mDrawable->findReferences(drawablep);
@@ -1377,15 +1457,15 @@ void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip
// Unknown parent, add to orpaned child list
U64 parent_info = getIndex(parent_id, ip, port);
- if (-1 == mOrphanParents.find(parent_info))
+ if (std::find(mOrphanParents.begin(), mOrphanParents.end(), parent_info) == mOrphanParents.end())
{
- mOrphanParents.put(parent_info);
+ mOrphanParents.push_back(parent_info);
}
LLViewerObjectList::OrphanInfo oi(parent_info, childp->mID);
- if (-1 == mOrphanChildren.find(oi))
+ if (std::find(mOrphanChildren.begin(), mOrphanChildren.end(), oi) == mOrphanChildren.end())
{
- mOrphanChildren.put(oi);
+ mOrphanChildren.push_back(oi);
mNumOrphans++;
}
}
@@ -1408,28 +1488,29 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
// See if we are a parent of an orphan.
// Note: This code is fairly inefficient but it should happen very rarely.
// It can be sped up if this is somehow a performance issue...
- if (0 == mOrphanParents.count())
+ if (mOrphanParents.empty())
{
// no known orphan parents
return;
}
- if (-1 == mOrphanParents.find(getIndex(objectp->mLocalID, ip, port)))
+ if (std::find(mOrphanParents.begin(), mOrphanParents.end(), getIndex(objectp->mLocalID, ip, port)) == mOrphanParents.end())
{
// did not find objectp in OrphanParent list
return;
}
- S32 i;
U64 parent_info = getIndex(objectp->mLocalID, ip, port);
BOOL orphans_found = FALSE;
// Iterate through the orphan list, and set parents of matching children.
- for (i = 0; i < mOrphanChildren.count(); i++)
- {
- if (mOrphanChildren[i].mParentInfo != parent_info)
+
+ for (std::vector<OrphanInfo>::iterator iter = mOrphanChildren.begin(); iter != mOrphanChildren.end(); )
+ {
+ if (iter->mParentInfo != parent_info)
{
+ ++iter;
continue;
}
- LLViewerObject *childp = findObject(mOrphanChildren[i].mChildInfo);
+ LLViewerObject *childp = findObject(iter->mChildInfo);
if (childp)
{
if (childp == objectp)
@@ -1463,40 +1544,46 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
objectp->addChild(childp);
orphans_found = TRUE;
+ ++iter;
}
else
{
llinfos << "Missing orphan child, removing from list" << llendl;
- mOrphanChildren.remove(i);
- i--;
+
+ iter = mOrphanChildren.erase(iter);
}
}
// Remove orphan parent and children from lists now that they've been found
- mOrphanParents.remove(mOrphanParents.find(parent_info));
-
- i = 0;
- while (i < mOrphanChildren.count())
{
- if (mOrphanChildren[i].mParentInfo == parent_info)
+ std::vector<U64>::iterator iter = std::find(mOrphanParents.begin(), mOrphanParents.end(), parent_info);
+ if (iter != mOrphanParents.end())
{
- mOrphanChildren.remove(i);
+ mOrphanParents.erase(iter);
+ }
+ }
+
+ for (std::vector<OrphanInfo>::iterator iter = mOrphanChildren.begin(); iter != mOrphanChildren.end(); )
+ {
+ if (iter->mParentInfo == parent_info)
+ {
+ iter = mOrphanChildren.erase(iter);
mNumOrphans--;
}
else
{
- i++;
+ ++iter;
}
}
if (orphans_found && objectp->isSelected())
{
- LLSelectNode* nodep = gSelectMgr->getSelection()->findNode(objectp);
+ LLSelectNode* nodep = LLSelectMgr::getInstance()->getSelection()->findNode(objectp);
if (nodep && !nodep->mIndividualSelection)
{
// rebuild selection with orphans
- gSelectMgr->deselectObjectAndFamily(objectp);
- gSelectMgr->selectObjectAndFamily(objectp);
+ LLSelectMgr::getInstance()->deselectObjectAndFamily(objectp);
+ LLSelectMgr::getInstance()->selectObjectAndFamily(objectp);
}
}
}
@@ -1504,6 +1591,7 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
////////////////////////////////////////////////////////////////////////////
LLViewerObjectList::OrphanInfo::OrphanInfo()
+ : mParentInfo(0)
{
}
@@ -1522,3 +1610,4 @@ bool LLViewerObjectList::OrphanInfo::operator!=(const OrphanInfo &rhs) const
return !operator==(rhs);
}
+