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:
@@ -731,6 +731,7 @@ LLVisualParam* LLWearable::getVisualParam(S32 index) const
|
|||||||
|
|
||||||
void LLWearable::getVisualParams(visual_param_vec_t &list)
|
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 iter = mVisualParamIndexMap.begin();
|
||||||
visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
|
visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
|
||||||
|
|
||||||
@@ -783,7 +784,7 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
|
|||||||
if (!avatarp) return;
|
if (!avatarp) return;
|
||||||
|
|
||||||
// Pull params
|
// 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
|
// 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.
|
// 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 );
|
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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "llextendedstatus.h"
|
#include "llextendedstatus.h"
|
||||||
#include "llpermissions.h"
|
#include "llpermissions.h"
|
||||||
#include "llsaleinfo.h"
|
#include "llsaleinfo.h"
|
||||||
|
#include "llsortedvector.h"
|
||||||
#include "llwearabletype.h"
|
#include "llwearabletype.h"
|
||||||
#include "lllocaltextureobject.h"
|
#include "lllocaltextureobject.h"
|
||||||
|
|
||||||
@@ -136,7 +137,7 @@ protected:
|
|||||||
typedef std::map<S32, F32> param_map_t;
|
typedef std::map<S32, F32> param_map_t;
|
||||||
param_map_t mSavedVisualParamMap; // last saved version of visual params
|
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;
|
visual_param_index_map_t mVisualParamIndexMap;
|
||||||
|
|
||||||
te_map_t mTEMap; // maps TE to LocalTextureObject
|
te_map_t mTEMap; // maps TE to LocalTextureObject
|
||||||
|
|||||||
@@ -267,8 +267,7 @@ BOOL LLWearableData::isOnTop(LLWearable* wearable) const
|
|||||||
|
|
||||||
const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) 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())
|
if (wearable_iter == mWearableDatas.end())
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -281,49 +280,79 @@ const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return wearable_vec[index];
|
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)
|
LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type)
|
||||||
{
|
{
|
||||||
U32 count = getWearableCount(type);
|
/*U32 count = getWearableCount(type);
|
||||||
if ( count == 0)
|
if ( count == 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
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
|
const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const
|
||||||
{
|
{
|
||||||
U32 count = getWearableCount(type);
|
/*U32 count = getWearableCount(type);
|
||||||
if ( count == 0)
|
if ( count == 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
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)
|
LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type)
|
||||||
{
|
{
|
||||||
if (getWearableCount(type) == 0)
|
/*if (getWearableCount(type) == 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
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
|
const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const
|
||||||
{
|
{
|
||||||
if (getWearableCount(type) == 0)
|
/*if (getWearableCount(type) == 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
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
|
U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "llavatarappearancedefines.h"
|
#include "llavatarappearancedefines.h"
|
||||||
#include "llwearable.h"
|
#include "llwearable.h"
|
||||||
#include "llerror.h"
|
#include "llerror.h"
|
||||||
|
#include "boost/array.hpp"
|
||||||
|
|
||||||
class LLAvatarAppearance;
|
class LLAvatarAppearance;
|
||||||
|
|
||||||
@@ -98,8 +99,34 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
LLAvatarAppearance* mAvatarAppearance;
|
LLAvatarAppearance* mAvatarAppearance;
|
||||||
typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
|
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
|
//typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
|
||||||
wearableentry_map_t mWearableDatas;
|
|
||||||
|
//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.
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -469,6 +469,7 @@ void LLCharacter::addSharedVisualParam(LLVisualParam *param)
|
|||||||
void LLCharacter::addVisualParam(LLVisualParam *param)
|
void LLCharacter::addVisualParam(LLVisualParam *param)
|
||||||
{
|
{
|
||||||
S32 index = param->getID();
|
S32 index = param->getID();
|
||||||
|
|
||||||
// Add Index map
|
// Add Index map
|
||||||
std::pair<visual_param_index_map_t::iterator, bool> idxres;
|
std::pair<visual_param_index_map_t::iterator, bool> idxres;
|
||||||
idxres = mVisualParamIndexMap.insert(visual_param_index_map_t::value_type(index, param));
|
idxres = mVisualParamIndexMap.insert(visual_param_index_map_t::value_type(index, param));
|
||||||
@@ -480,6 +481,8 @@ void LLCharacter::addVisualParam(LLVisualParam *param)
|
|||||||
index_iter->second = param;
|
index_iter->second = param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mVisualParamSortedVector[index] = param;
|
||||||
|
|
||||||
if (param->getInfo())
|
if (param->getInfo())
|
||||||
{
|
{
|
||||||
// Add name map
|
// Add name map
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
#include "string_table.h"
|
#include "string_table.h"
|
||||||
#include "llpointer.h"
|
#include "llpointer.h"
|
||||||
#include "llthread.h"
|
#include "llthread.h"
|
||||||
|
#include "llsortedvector.h"
|
||||||
|
#include <boost/unordered_map.hpp>
|
||||||
|
|
||||||
class LLPolyMesh;
|
class LLPolyMesh;
|
||||||
|
|
||||||
@@ -208,12 +210,12 @@ public:
|
|||||||
// visual parameter accessors
|
// visual parameter accessors
|
||||||
LLVisualParam* getFirstVisualParam()
|
LLVisualParam* getFirstVisualParam()
|
||||||
{
|
{
|
||||||
mCurIterator = mVisualParamIndexMap.begin();
|
mCurIterator = mVisualParamSortedVector.begin();
|
||||||
return getNextVisualParam();
|
return getNextVisualParam();
|
||||||
}
|
}
|
||||||
LLVisualParam* getNextVisualParam()
|
LLVisualParam* getNextVisualParam()
|
||||||
{
|
{
|
||||||
if (mCurIterator == mVisualParamIndexMap.end())
|
if (mCurIterator == mVisualParamSortedVector.end())
|
||||||
return 0;
|
return 0;
|
||||||
return (mCurIterator++)->second;
|
return (mCurIterator++)->second;
|
||||||
}
|
}
|
||||||
@@ -221,8 +223,8 @@ public:
|
|||||||
S32 getVisualParamCountInGroup(const EVisualParamGroup group) const
|
S32 getVisualParamCountInGroup(const EVisualParamGroup group) const
|
||||||
{
|
{
|
||||||
S32 rtn = 0;
|
S32 rtn = 0;
|
||||||
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
|
for (visual_param_sorted_vec_t::const_iterator iter = mVisualParamSortedVector.begin();
|
||||||
iter != mVisualParamIndexMap.end();
|
iter != mVisualParamSortedVector.end();
|
||||||
/* */ )
|
/* */ )
|
||||||
{
|
{
|
||||||
if ((iter++)->second->getGroup() == group)
|
if ((iter++)->second->getGroup() == group)
|
||||||
@@ -238,7 +240,7 @@ public:
|
|||||||
visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id);
|
visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id);
|
||||||
return (iter == mVisualParamIndexMap.end()) ? 0 : iter->second;
|
return (iter == mVisualParamIndexMap.end()) ? 0 : iter->second;
|
||||||
}
|
}
|
||||||
S32 getVisualParamID(LLVisualParam *id)
|
/*S32 getVisualParamID(LLVisualParam *id)
|
||||||
{
|
{
|
||||||
visual_param_index_map_t::iterator iter;
|
visual_param_index_map_t::iterator iter;
|
||||||
for (iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
|
for (iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
|
||||||
@@ -247,7 +249,7 @@ public:
|
|||||||
return iter->first;
|
return iter->first;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}*/
|
||||||
S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); }
|
S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); }
|
||||||
LLVisualParam* getVisualParam(const char *name);
|
LLVisualParam* getVisualParam(const char *name);
|
||||||
|
|
||||||
@@ -278,13 +280,15 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// visual parameter stuff
|
// visual parameter stuff
|
||||||
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
|
//typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
|
||||||
typedef std::map<char *, LLVisualParam *> visual_param_name_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.
|
||||||
visual_param_index_map_t::iterator mCurIterator;
|
typedef std::map<char *, LLVisualParam *> visual_param_name_map_t;
|
||||||
visual_param_index_map_t mVisualParamIndexMap;
|
|
||||||
visual_param_name_map_t mVisualParamNameMap;
|
|
||||||
|
|
||||||
|
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;
|
static LLStringTable sVisualParamNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -83,13 +83,7 @@ LLMotionRegistry::~LLMotionRegistry()
|
|||||||
BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor )
|
BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor )
|
||||||
{
|
{
|
||||||
// llinfos << "Registering motion: " << name << llendl;
|
// llinfos << "Registering motion: " << name << llendl;
|
||||||
if (!is_in_map(mMotionTable, id))
|
return mMotionTable.insert(std::make_pair(id,constructor)).second;
|
||||||
{
|
|
||||||
mMotionTable[id] = constructor;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -109,6 +109,16 @@ public:
|
|||||||
return const_cast<self*>(this)->find(key);
|
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:
|
private:
|
||||||
// Define our own 'less' comparator so we can specialize without messing
|
// Define our own 'less' comparator so we can specialize without messing
|
||||||
// with std::less.
|
// with std::less.
|
||||||
|
|||||||
@@ -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.
|
// helper function which returns true if key is in inmap.
|
||||||
template <typename K, typename T>
|
template <typename T>
|
||||||
inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
|
//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())
|
if(inmap.find(key) == inmap.end())
|
||||||
{
|
{
|
||||||
return false;
|
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:
|
// To replace LLSkipMap getIfThere, use:
|
||||||
// get_if_there(map, key, 0)
|
// get_if_there(map, key, 0)
|
||||||
// WARNING: Make sure default_value (generally 0) is not a valid map entry!
|
// 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 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);
|
map_iter iter = inmap.find(key);
|
||||||
if(iter == inmap.end())
|
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
|
// Useful for replacing the removeObj() functionality of LLDynamicArray
|
||||||
// Example:
|
// Example:
|
||||||
// for (std::vector<T>::iterator iter = mList.begin(); iter != mList.end(); )
|
// 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
|
// else
|
||||||
// ++iter;
|
// ++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())
|
if (iter == invec.end())
|
||||||
{
|
{
|
||||||
return iter;
|
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
|
// Useful for replacing the removeObj() functionality of LLDynamicArray
|
||||||
// Example:
|
// Example:
|
||||||
// vector_replace_with_last(mList, x);
|
// vector_replace_with_last(mList, x);
|
||||||
|
//
|
||||||
|
//Singu note: This has been generalized to support a broader range of sequence containers
|
||||||
template <typename T>
|
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())
|
if (iter != invec.end())
|
||||||
{
|
{
|
||||||
typename std::vector<T>::iterator last = invec.end(); --last;
|
typename T::iterator last = invec.end(); --last;
|
||||||
*iter = *last;
|
*iter = *last;
|
||||||
invec.pop_back();
|
invec.pop_back();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1495,7 +1495,7 @@ void LLAgentCamera::updateCamera()
|
|||||||
|
|
||||||
gAgentAvatarp->mRoot->updateWorldMatrixChildren();
|
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(); )
|
iter != gAgentAvatarp->mAttachmentPoints.end(); )
|
||||||
{
|
{
|
||||||
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
|
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
|
||||||
@@ -1504,7 +1504,11 @@ void LLAgentCamera::updateCamera()
|
|||||||
attachment_iter != attachment->mAttachedObjects.end();
|
attachment_iter != attachment->mAttachedObjects.end();
|
||||||
++attachment_iter)
|
++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())
|
if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
|
||||||
{
|
{
|
||||||
// clear any existing "early" movements of attachment
|
// clear any existing "early" movements of attachment
|
||||||
|
|||||||
@@ -1063,13 +1063,14 @@ void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id)
|
|||||||
return;
|
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 "
|
llwarns << "Could not move inventory object " << object_id << " to "
|
||||||
<< cat_id << llendl;
|
<< cat_id << llendl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LLViewerInventoryCategory* cat = getCategory(object_id);
|
LLViewerInventoryCategory* cat = it->second;
|
||||||
if(cat && (cat->getParentUUID() != cat_id))
|
if(cat && (cat->getParentUUID() != cat_id))
|
||||||
{
|
{
|
||||||
cat_array_t* cat_array;
|
cat_array_t* cat_array;
|
||||||
|
|||||||
@@ -1006,6 +1006,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
|
|||||||
mCCSChatTextOverride(false)
|
mCCSChatTextOverride(false)
|
||||||
// </edit>
|
// </edit>
|
||||||
{
|
{
|
||||||
|
mAttachedObjectsVector.reserve(MAX_AGENT_ATTACHMENTS);
|
||||||
|
|
||||||
static LLCachedControl<bool> const freeze_time("FreezeTime", false);
|
static LLCachedControl<bool> const freeze_time("FreezeTime", false);
|
||||||
mFreezeTimeLangolier = freeze_time;
|
mFreezeTimeLangolier = freeze_time;
|
||||||
|
|
||||||
@@ -1115,7 +1117,7 @@ LLVOAvatar::~LLVOAvatar()
|
|||||||
lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
|
lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
|
||||||
|
|
||||||
std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
|
std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
|
||||||
mAttachmentPoints.clear();
|
//mAttachmentPoints.clear();
|
||||||
|
|
||||||
mDead = TRUE;
|
mDead = TRUE;
|
||||||
|
|
||||||
@@ -1645,7 +1647,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
|
|||||||
mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
|
mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
|
||||||
|
|
||||||
//stretch bounding box by attachments
|
//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 != mAttachmentPoints.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
@@ -1660,7 +1662,13 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
|
|||||||
attachment_iter != attachment->mAttachedObjects.end();
|
attachment_iter != attachment->mAttachedObjects.end();
|
||||||
++attachment_iter)
|
++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())
|
if (attached_object && !attached_object->isHUDAttachment())
|
||||||
{
|
{
|
||||||
LLDrawable* drawable = attached_object->mDrawable;
|
LLDrawable* drawable = attached_object->mDrawable;
|
||||||
@@ -2494,7 +2502,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
|
|||||||
if (detailed_update || !sUseImpostors)
|
if (detailed_update || !sUseImpostors)
|
||||||
{
|
{
|
||||||
LLFastTimer t(FTM_ATTACHMENT_UPDATE);
|
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 != mAttachmentPoints.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
@@ -2504,7 +2512,12 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
|
|||||||
attachment_iter != attachment->mAttachedObjects.end();
|
attachment_iter != attachment->mAttachedObjects.end();
|
||||||
++attachment_iter)
|
++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 &&
|
BOOL visibleAttachment = visible || (attached_object &&
|
||||||
!(attached_object->mDrawable->getSpatialBridge() &&
|
!(attached_object->mDrawable->getSpatialBridge() &&
|
||||||
attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0));
|
attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0));
|
||||||
@@ -2964,7 +2977,7 @@ void LLVOAvatar::idleCCSUpdateAttachmentText(bool render_name)
|
|||||||
if(!mCCSUpdateAttachmentTimer.checkExpirationAndReset(SECS_BETWEEN_UPDATES))
|
if(!mCCSUpdateAttachmentTimer.checkExpirationAndReset(SECS_BETWEEN_UPDATES))
|
||||||
return;
|
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
|
// get attached object
|
||||||
LLViewerJointAttachment *joint = it->second;
|
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();
|
for(std::vector<LLViewerObject *>::const_iterator parent_it = joint->mAttachedObjects.begin();
|
||||||
parent_it != joint->mAttachedObjects.end(); ++parent_it)
|
parent_it != joint->mAttachedObjects.end(); ++parent_it)
|
||||||
{
|
{
|
||||||
LLViewerObject* pObject = (*parent_it);
|
LLViewerObject* pObject = (*parent_it);*/
|
||||||
const LLTextureEntry *te = pObject ? pObject->getTE(0) : NULL;
|
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;
|
if(!te) continue;
|
||||||
const LLColor4 &col = te->getColor();
|
const LLColor4 &col = te->getColor();
|
||||||
if( (fabs(col[0] - 0.012f) < 0.001f) &&
|
if( (fabs(col[0] - 0.012f) < 0.001f) &&
|
||||||
@@ -6228,6 +6247,8 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
|
|||||||
LLSelectMgr::getInstance()->updatePointAt();
|
LLSelectMgr::getInstance()->updatePointAt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mAttachedObjectsVector.push_back(std::make_pair(viewer_object,attachment));
|
||||||
|
|
||||||
return attachment;
|
return attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6382,6 +6403,13 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
|
|||||||
{
|
{
|
||||||
cleanupAttachedMesh( viewer_object );
|
cleanupAttachedMesh( viewer_object );
|
||||||
attachment->removeObject(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;
|
lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -8755,7 +8783,7 @@ void LLVOAvatar::idleUpdateRenderCost()
|
|||||||
|
|
||||||
std::set<LLUUID> textures;
|
std::set<LLUUID> textures;
|
||||||
|
|
||||||
attachment_map_t::const_iterator iter;
|
/*attachment_map_t::const_iterator iter;
|
||||||
for (iter = mAttachmentPoints.begin();
|
for (iter = mAttachmentPoints.begin();
|
||||||
iter != mAttachmentPoints.end();
|
iter != mAttachmentPoints.end();
|
||||||
++iter)
|
++iter)
|
||||||
@@ -8765,7 +8793,11 @@ void LLVOAvatar::idleUpdateRenderCost()
|
|||||||
attachment_iter != attachment->mAttachedObjects.end();
|
attachment_iter != attachment->mAttachedObjects.end();
|
||||||
++attachment_iter)
|
++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())
|
if (object && !object->isHUDAttachment())
|
||||||
{
|
{
|
||||||
LLDrawable* drawable = object->mDrawable;
|
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 != mAttachmentPoints.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
@@ -8826,7 +8858,11 @@ void LLVOAvatar::idleUpdateRenderCost()
|
|||||||
attachment_iter != attachment->mAttachedObjects.end();
|
attachment_iter != attachment->mAttachedObjects.end();
|
||||||
++attachment_iter)
|
++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())
|
if (attached_object && !attached_object->isHUDAttachment())
|
||||||
{
|
{
|
||||||
textures.clear();
|
textures.clear();
|
||||||
|
|||||||
@@ -745,9 +745,11 @@ protected:
|
|||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
public:
|
public:
|
||||||
S32 getAttachmentCount(); // Warning: order(N) not order(1) // currently used only by -self
|
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;
|
attachment_map_t mAttachmentPoints;
|
||||||
std::vector<LLPointer<LLViewerObject> > mPendingAttachment;
|
std::vector<LLPointer<LLViewerObject> > mPendingAttachment;
|
||||||
|
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> > mAttachedObjectsVector; //A vector of all current attachments for fast iteration.
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// HUD functions
|
// HUD functions
|
||||||
|
|||||||
@@ -9616,7 +9616,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
|
|||||||
markVisible(avatar->mDrawable, *viewer_camera);
|
markVisible(avatar->mDrawable, *viewer_camera);
|
||||||
LLVOAvatar::sUseImpostors = FALSE;
|
LLVOAvatar::sUseImpostors = FALSE;
|
||||||
|
|
||||||
LLVOAvatar::attachment_map_t::iterator iter;
|
/*LLVOAvatar::attachment_map_t::iterator iter;
|
||||||
for (iter = avatar->mAttachmentPoints.begin();
|
for (iter = avatar->mAttachmentPoints.begin();
|
||||||
iter != avatar->mAttachmentPoints.end();
|
iter != avatar->mAttachmentPoints.end();
|
||||||
++iter)
|
++iter)
|
||||||
@@ -9626,7 +9626,12 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
|
|||||||
attachment_iter != attachment->mAttachedObjects.end();
|
attachment_iter != attachment->mAttachedObjects.end();
|
||||||
++attachment_iter)
|
++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);
|
markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user