Attempt to speed up agent idle update by optimizing wearable/visualparam related lookups/iterations a bit more.

Generalized several templates in llstl.h in order to support more containers.
Removed several instances of is_in_map/getWearableCount being followed immediately by another lookup with the same key. find is more efficient, as we get an iterator to use instead of a simple boolean.
This commit is contained in:
Shyotl
2013-04-24 17:52:17 -05:00
parent 6f415118ef
commit ef9fbe2193
14 changed files with 210 additions and 89 deletions

View File

@@ -731,6 +731,7 @@ LLVisualParam* LLWearable::getVisualParam(S32 index) const
void LLWearable::getVisualParams(visual_param_vec_t &list)
{
list.reserve(mVisualParamIndexMap.size());
visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
@@ -783,7 +784,7 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
if (!avatarp) return;
// Pull params
for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
/*for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
{
// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
@@ -794,6 +795,12 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
avatarp->setVisualParamWeight( param_id, weight, FALSE );
}
}*/
for( visual_param_index_map_t::iterator it = mVisualParamIndexMap.begin(); it != mVisualParamIndexMap.end(); ++it )
{
LLVisualParam* param = it->second;
if(!((LLViewerVisualParam*)param)->getCrossWearable())
avatarp->setVisualParamWeight( param->getID(), param->getWeight(), FALSE );
}
}

View File

@@ -31,6 +31,7 @@
#include "llextendedstatus.h"
#include "llpermissions.h"
#include "llsaleinfo.h"
#include "llsortedvector.h"
#include "llwearabletype.h"
#include "lllocaltextureobject.h"
@@ -136,7 +137,7 @@ protected:
typedef std::map<S32, F32> param_map_t;
param_map_t mSavedVisualParamMap; // last saved version of visual params
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
typedef LLSortedVector<S32, LLVisualParam *> visual_param_index_map_t;
visual_param_index_map_t mVisualParamIndexMap;
te_map_t mTEMap; // maps TE to LocalTextureObject

View File

@@ -267,8 +267,7 @@ BOOL LLWearableData::isOnTop(LLWearable* wearable) const
const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) const
{
//llassert_always(index == 0);
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
/*wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
return NULL;
@@ -281,49 +280,79 @@ const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type,
else
{
return wearable_vec[index];
}*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && index < wearable_iter->second.size())
{
return wearable_iter->second[index];
}
return NULL;
}
LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type)
{
U32 count = getWearableCount(type);
/*U32 count = getWearableCount(type);
if ( count == 0)
{
return NULL;
}
return getWearable(type, count-1);
return getWearable(type, count-1);*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
{
return wearable_iter->second.back();
}
return NULL;
}
const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const
{
U32 count = getWearableCount(type);
/*U32 count = getWearableCount(type);
if ( count == 0)
{
return NULL;
}
return getWearable(type, count-1);
return getWearable(type, count-1);*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
{
return wearable_iter->second.back();
}
return NULL;
}
LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type)
{
if (getWearableCount(type) == 0)
/*if (getWearableCount(type) == 0)
{
return NULL;
}
return getWearable(type, 0);
return getWearable(type, 0);*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
{
return wearable_iter->second.front();
}
return NULL;
}
const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const
{
if (getWearableCount(type) == 0)
/*if (getWearableCount(type) == 0)
{
return NULL;
}
return getWearable(type, 0);
return getWearable(type, 0);*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
{
return wearable_iter->second.front();
}
return NULL;
}
U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const

View File

@@ -30,6 +30,7 @@
#include "llavatarappearancedefines.h"
#include "llwearable.h"
#include "llerror.h"
#include "boost/array.hpp"
class LLAvatarAppearance;
@@ -98,8 +99,34 @@ protected:
protected:
LLAvatarAppearance* mAvatarAppearance;
typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
wearableentry_map_t mWearableDatas;
//typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
//Why this weird structure? LLWearableType::WT_COUNT small and known, therefore it's more efficient to make an array of vectors, indexed
//by wearable type. This allows O(1) lookups. This structure simply lets us plug in this optimization without touching any code elsewhere.
typedef boost::array<std::pair<LLWearableType::EType,wearableentry_vec_t>,LLWearableType::WT_COUNT> wearable_array_t;
struct wearableentry_map_t : public wearable_array_t
{
wearableentry_map_t()
{
for(wearable_array_t::size_type i=0;i<size();++i)
at(i).first = (LLWearableType::EType)i;
}
wearable_array_t::iterator find(const LLWearableType::EType& index)
{
if(index < 0 || index >= (S32)size())
return end();
return begin() + index;
}
wearable_array_t::const_iterator find(const LLWearableType::EType& index) const
{
if(index < 0 || index >= (S32)size())
return end();
return begin() + index;
}
wearableentry_vec_t& operator [] (const S32 index) { return at(index).second; }
const wearableentry_vec_t& operator [] (const S32 index) const { return at(index).second; }
};
wearableentry_map_t mWearableDatas; //Array for quicker lookups.
};

View File

@@ -469,6 +469,7 @@ void LLCharacter::addSharedVisualParam(LLVisualParam *param)
void LLCharacter::addVisualParam(LLVisualParam *param)
{
S32 index = param->getID();
// Add Index map
std::pair<visual_param_index_map_t::iterator, bool> idxres;
idxres = mVisualParamIndexMap.insert(visual_param_index_map_t::value_type(index, param));
@@ -479,6 +480,8 @@ void LLCharacter::addVisualParam(LLVisualParam *param)
visual_param_index_map_t::iterator index_iter = idxres.first;
index_iter->second = param;
}
mVisualParamSortedVector[index] = param;
if (param->getInfo())
{

View File

@@ -38,6 +38,8 @@
#include "string_table.h"
#include "llpointer.h"
#include "llthread.h"
#include "llsortedvector.h"
#include <boost/unordered_map.hpp>
class LLPolyMesh;
@@ -208,21 +210,21 @@ public:
// visual parameter accessors
LLVisualParam* getFirstVisualParam()
{
mCurIterator = mVisualParamIndexMap.begin();
mCurIterator = mVisualParamSortedVector.begin();
return getNextVisualParam();
}
LLVisualParam* getNextVisualParam()
{
if (mCurIterator == mVisualParamIndexMap.end())
if (mCurIterator == mVisualParamSortedVector.end())
return 0;
return (mCurIterator++)->second;
}
S32 getVisualParamCountInGroup(const EVisualParamGroup group) const
{
S32 rtn = 0;
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
iter != mVisualParamIndexMap.end();
for (visual_param_sorted_vec_t::const_iterator iter = mVisualParamSortedVector.begin();
iter != mVisualParamSortedVector.end();
/* */ )
{
if ((iter++)->second->getGroup() == group)
@@ -238,7 +240,7 @@ public:
visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id);
return (iter == mVisualParamIndexMap.end()) ? 0 : iter->second;
}
S32 getVisualParamID(LLVisualParam *id)
/*S32 getVisualParamID(LLVisualParam *id)
{
visual_param_index_map_t::iterator iter;
for (iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
@@ -247,7 +249,7 @@ public:
return iter->first;
}
return 0;
}
}*/
S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); }
LLVisualParam* getVisualParam(const char *name);
@@ -278,13 +280,15 @@ protected:
private:
// visual parameter stuff
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
typedef std::map<char *, LLVisualParam *> visual_param_name_map_t;
visual_param_index_map_t::iterator mCurIterator;
visual_param_index_map_t mVisualParamIndexMap;
visual_param_name_map_t mVisualParamNameMap;
//typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
typedef boost::unordered_map<S32, LLVisualParam *> visual_param_index_map_t; //Hash map for fast lookup.
typedef LLSortedVector<S32,LLVisualParam *> visual_param_sorted_vec_t; //Contiguous sorted array.
typedef std::map<char *, LLVisualParam *> visual_param_name_map_t;
visual_param_sorted_vec_t::iterator mCurIterator;
visual_param_sorted_vec_t mVisualParamSortedVector;
visual_param_index_map_t mVisualParamIndexMap;
visual_param_name_map_t mVisualParamNameMap;
static LLStringTable sVisualParamNames;
};

View File

@@ -83,13 +83,7 @@ LLMotionRegistry::~LLMotionRegistry()
BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor )
{
// llinfos << "Registering motion: " << name << llendl;
if (!is_in_map(mMotionTable, id))
{
mMotionTable[id] = constructor;
return TRUE;
}
return FALSE;
return mMotionTable.insert(std::make_pair(id,constructor)).second;
}
//-----------------------------------------------------------------------------

View File

@@ -109,6 +109,16 @@ public:
return const_cast<self*>(this)->find(key);
}
//For easy insertion shorthand. Eases std::map => LLSortedVector drop-in replacement.
mapped_type& operator[] (const key_type& key)
{
return insert(std::make_pair(key,mapped_type())).first->second;
}
const mapped_type& operator[] (const key_type& key) const
{
return insert(std::make_pair(key,mapped_type())).first->second;
}
private:
// Define our own 'less' comparator so we can specialize without messing
// with std::less.

View File

@@ -175,35 +175,12 @@ struct CopyNewPointer
}
};
// Simple function to help with finding pointers in maps.
// For example:
// typedef map_t;
// std::map<int, const char*> foo;
// foo[18] = "there";
// foo[2] = "hello";
// const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello"
// const char* baz = get_ptr_in_map(foo, 3); // baz == NULL
template <typename K, typename T>
inline T* get_ptr_in_map(const std::map<K,T*>& inmap, const K& key)
{
// Typedef here avoids warnings because of new c++ naming rules.
typedef typename std::map<K,T*>::const_iterator map_iter;
map_iter iter = inmap.find(key);
if(iter == inmap.end())
{
return NULL;
}
else
{
return iter->second;
}
};
// helper function which returns true if key is in inmap.
template <typename K, typename T>
inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
template <typename T>
//Singu note: This has been generalized to support a broader range of map-esque containers
inline bool is_in_map(const T& inmap, typename const T::key_type& key)
{
typedef typename std::map<K,T>::const_iterator map_iter;
typedef typename T::const_iterator map_iter;
if(inmap.find(key) == inmap.end())
{
return false;
@@ -218,11 +195,13 @@ inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
// To replace LLSkipMap getIfThere, use:
// get_if_there(map, key, 0)
// WARNING: Make sure default_value (generally 0) is not a valid map entry!
template <typename K, typename T>
inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
//
//Singu note: This has been generalized to support a broader range of map-esque containers.
template <typename T>
inline typename T::mapped_type get_if_there(const T& inmap, typename const T::key_type& key, typename T::mapped_type default_value)
{
// Typedef here avoids warnings because of new c++ naming rules.
typedef typename std::map<K,T>::const_iterator map_iter;
typedef typename T::const_iterator map_iter;
map_iter iter = inmap.find(key);
if(iter == inmap.end())
{
@@ -234,6 +213,21 @@ inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
}
};
// Simple function to help with finding pointers in maps.
// For example:
// typedef map_t;
// std::map<int, const char*> foo;
// foo[18] = "there";
// foo[2] = "hello";
// const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello"
// const char* baz = get_ptr_in_map(foo, 3); // baz == NULL
//Singu note: This has been generalized to support a broader range of map-esque containers
template <typename T>
inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename const T::key_type& key)
{
return get_if_there(inmap,key,NULL);
};
// Useful for replacing the removeObj() functionality of LLDynamicArray
// Example:
// for (std::vector<T>::iterator iter = mList.begin(); iter != mList.end(); )
@@ -243,10 +237,12 @@ inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
// else
// ++iter;
// }
template <typename T, typename Iter>
inline Iter vector_replace_with_last(std::vector<T>& invec, Iter iter)
//
//Singu note: This has been generalized to support a broader range of sequence containers
template <typename T>
inline typename T::iterator vector_replace_with_last(T& invec, typename T::iterator& iter)
{
typename std::vector<T>::iterator last = invec.end(); --last;
typename T::iterator last = invec.end(); --last;
if (iter == invec.end())
{
return iter;
@@ -267,13 +263,15 @@ inline Iter vector_replace_with_last(std::vector<T>& invec, Iter iter)
// Useful for replacing the removeObj() functionality of LLDynamicArray
// Example:
// vector_replace_with_last(mList, x);
//
//Singu note: This has been generalized to support a broader range of sequence containers
template <typename T>
inline bool vector_replace_with_last(std::vector<T>& invec, const T& val)
inline bool vector_replace_with_last(T& invec, typename const T::value_type& val)
{
typename std::vector<T>::iterator iter = std::find(invec.begin(), invec.end(), val);
typename T::iterator iter = std::find(invec.begin(), invec.end(), val);
if (iter != invec.end())
{
typename std::vector<T>::iterator last = invec.end(); --last;
typename T::iterator last = invec.end(); --last;
*iter = *last;
invec.pop_back();
return true;

View File

@@ -1495,7 +1495,7 @@ void LLAgentCamera::updateCamera()
gAgentAvatarp->mRoot->updateWorldMatrixChildren();
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
/*for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); //Can be an array.
iter != gAgentAvatarp->mAttachmentPoints.end(); )
{
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
@@ -1504,7 +1504,11 @@ void LLAgentCamera::updateCamera()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
LLViewerObject *attached_object = (*attachment_iter);
LLViewerObject *attached_object = (*attachment_iter);*/
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator attachment_iter = gAgentAvatarp->mAttachedObjectsVector.begin();
for(;attachment_iter!=gAgentAvatarp->mAttachedObjectsVector.end();++attachment_iter)
{{
LLViewerObject* attached_object = attachment_iter->first;
if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
{
// clear any existing "early" movements of attachment

View File

@@ -1063,13 +1063,14 @@ void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id)
return;
}
if((object_id == cat_id) || !is_in_map(mCategoryMap, cat_id))
cat_map_t::iterator it;
if((object_id == cat_id) || (it = mCategoryMap.find(cat_id))==mCategoryMap.end())
{
llwarns << "Could not move inventory object " << object_id << " to "
<< cat_id << llendl;
return;
}
LLViewerInventoryCategory* cat = getCategory(object_id);
LLViewerInventoryCategory* cat = it->second;
if(cat && (cat->getParentUUID() != cat_id))
{
cat_array_t* cat_array;

View File

@@ -1006,6 +1006,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mCCSChatTextOverride(false)
// </edit>
{
mAttachedObjectsVector.reserve(MAX_AGENT_ATTACHMENTS);
static LLCachedControl<bool> const freeze_time("FreezeTime", false);
mFreezeTimeLangolier = freeze_time;
@@ -1115,7 +1117,7 @@ LLVOAvatar::~LLVOAvatar()
lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
mAttachmentPoints.clear();
//mAttachmentPoints.clear();
mDead = TRUE;
@@ -1645,7 +1647,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
//stretch bounding box by attachments
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
/*for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
{
@@ -1660,7 +1662,13 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
const LLViewerObject* attached_object = (*attachment_iter);
const LLViewerObject* attached_object = (*attachment_iter);*/
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator attachment_iter = mAttachedObjectsVector.begin();
for(;attachment_iter!=mAttachedObjectsVector.end();++attachment_iter)
{
if(attachment_iter->second->getValid())
{
const LLViewerObject* attached_object = attachment_iter->first;
if (attached_object && !attached_object->isHUDAttachment())
{
LLDrawable* drawable = attached_object->mDrawable;
@@ -2494,7 +2502,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (detailed_update || !sUseImpostors)
{
LLFastTimer t(FTM_ATTACHMENT_UPDATE);
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
/*for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
{
@@ -2504,7 +2512,12 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
LLViewerObject* attached_object = (*attachment_iter);
LLViewerObject* attached_object = (*attachment_iter);*/
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator attachment_iter = mAttachedObjectsVector.begin();
for(;attachment_iter!=mAttachedObjectsVector.end();++attachment_iter)
{{
LLViewerJointAttachment* attachment = attachment_iter->second;
LLViewerObject* attached_object = attachment_iter->first;
BOOL visibleAttachment = visible || (attached_object &&
!(attached_object->mDrawable->getSpatialBridge() &&
attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0));
@@ -2964,7 +2977,7 @@ void LLVOAvatar::idleCCSUpdateAttachmentText(bool render_name)
if(!mCCSUpdateAttachmentTimer.checkExpirationAndReset(SECS_BETWEEN_UPDATES))
return;
for (attachment_map_t::iterator it=mAttachmentPoints.begin(); it!=mAttachmentPoints.end(); ++it)
/*for (attachment_map_t::iterator it=mAttachmentPoints.begin(); it!=mAttachmentPoints.end(); ++it)
{
// get attached object
LLViewerJointAttachment *joint = it->second;
@@ -2973,8 +2986,14 @@ void LLVOAvatar::idleCCSUpdateAttachmentText(bool render_name)
for(std::vector<LLViewerObject *>::const_iterator parent_it = joint->mAttachedObjects.begin();
parent_it != joint->mAttachedObjects.end(); ++parent_it)
{
LLViewerObject* pObject = (*parent_it);
const LLTextureEntry *te = pObject ? pObject->getTE(0) : NULL;
LLViewerObject* pObject = (*parent_it);*/
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator parent_it = mAttachedObjectsVector.begin();
for(;parent_it!=mAttachedObjectsVector.end();++parent_it)
{{
LLViewerObject* pObject = parent_it->first;
if(!pObject)
continue;
const LLTextureEntry *te = pObject->getTE(0);
if(!te) continue;
const LLColor4 &col = te->getColor();
if( (fabs(col[0] - 0.012f) < 0.001f) &&
@@ -6228,6 +6247,8 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
LLSelectMgr::getInstance()->updatePointAt();
}
mAttachedObjectsVector.push_back(std::make_pair(viewer_object,attachment));
return attachment;
}
@@ -6382,6 +6403,13 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
{
cleanupAttachedMesh( viewer_object );
attachment->removeObject(viewer_object);
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator it = std::find(mAttachedObjectsVector.begin(),mAttachedObjectsVector.end(),std::make_pair(viewer_object,attachment));
if(it != mAttachedObjectsVector.end())
{
(*it) = mAttachedObjectsVector.back();
mAttachedObjectsVector.pop_back();
}
lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl;
return TRUE;
}
@@ -8755,7 +8783,7 @@ void LLVOAvatar::idleUpdateRenderCost()
std::set<LLUUID> textures;
attachment_map_t::const_iterator iter;
/*attachment_map_t::const_iterator iter;
for (iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -8765,7 +8793,11 @@ void LLVOAvatar::idleUpdateRenderCost()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
const LLViewerObject* object = (*attachment_iter);
const LLViewerObject* object = (*attachment_iter);*/
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator attachment_iter = mAttachedObjectsVector.begin();
for(;attachment_iter!=mAttachedObjectsVector.end();++attachment_iter)
{{
const LLViewerObject* object = attachment_iter->first;
if (object && !object->isHUDAttachment())
{
LLDrawable* drawable = object->mDrawable;
@@ -8817,7 +8849,7 @@ void LLVOAvatar::idleUpdateRenderCost()
}
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
/*for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
{
@@ -8826,7 +8858,11 @@ void LLVOAvatar::idleUpdateRenderCost()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
const LLViewerObject* attached_object = (*attachment_iter);
const LLViewerObject* attached_object = (*attachment_iter);*/
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator attachment_iter = mAttachedObjectsVector.begin();
for(;attachment_iter!=mAttachedObjectsVector.end();++attachment_iter)
{{
const LLViewerObject* attached_object = attachment_iter->first;
if (attached_object && !attached_object->isHUDAttachment())
{
textures.clear();

View File

@@ -745,9 +745,11 @@ protected:
//--------------------------------------------------------------------
public:
S32 getAttachmentCount(); // Warning: order(N) not order(1) // currently used only by -self
typedef std::map<S32, LLViewerJointAttachment*> attachment_map_t;
//typedef std::map<S32, LLViewerJointAttachment*> attachment_map_t;
typedef LLSortedVector<S32, LLViewerJointAttachment*> attachment_map_t;
attachment_map_t mAttachmentPoints;
std::vector<LLPointer<LLViewerObject> > mPendingAttachment;
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> > mAttachedObjectsVector; //A vector of all current attachments for fast iteration.
//--------------------------------------------------------------------
// HUD functions

View File

@@ -9616,7 +9616,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
markVisible(avatar->mDrawable, *viewer_camera);
LLVOAvatar::sUseImpostors = FALSE;
LLVOAvatar::attachment_map_t::iterator iter;
/*LLVOAvatar::attachment_map_t::iterator iter;
for (iter = avatar->mAttachmentPoints.begin();
iter != avatar->mAttachmentPoints.end();
++iter)
@@ -9626,7 +9626,12 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
if (LLViewerObject* attached_object = (*attachment_iter))
if (LLViewerObject* attached_object = (*attachment_iter))*/
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator attachment_iter = avatar->mAttachedObjectsVector.begin();
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator end = avatar->mAttachedObjectsVector.end();
for(;attachment_iter != end;++attachment_iter)
{{
if (LLViewerObject* attached_object = attachment_iter->first)
{
markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
}