diff options
25 files changed, 747 insertions, 537 deletions
| diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt index 0206f76546..41da898457 100644 --- a/indra/llappearance/CMakeLists.txt +++ b/indra/llappearance/CMakeLists.txt @@ -42,6 +42,7 @@ include_directories(  set(llappearance_SOURCE_FILES      llavatarappearance.cpp +    lldriverparam.cpp      llinventoryicon.cpp      lllocaltextureobject.cpp      lltexglobalcolor.cpp @@ -49,6 +50,7 @@ set(llappearance_SOURCE_FILES      lltexlayerparams.cpp      lltexturemanagerbridge.cpp      llwearable.cpp +    llwearabledata.cpp      llwearabletype.cpp      llviewervisualparam.cpp      llavatarappearancedefines.cpp @@ -58,6 +60,7 @@ set(llappearance_HEADER_FILES      CMakeLists.txt      llavatarappearance.h +    lldriverparam.h      llinventoryicon.h      lljointpickname.h      lllocaltextureobject.h @@ -66,6 +69,7 @@ set(llappearance_HEADER_FILES      lltexlayerparams.h      lltexturemanagerbridge.h      llwearable.h +    llwearabledata.h      llwearabletype.h      llviewervisualparam.h      llavatarappearancedefines.h diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 75b9c1ffa5..0f0942d8dc 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -29,16 +29,19 @@  #include "llavatarappearance.h"  #include "lldeleteutils.h"  #include "lltexglobalcolor.h" +#include "llwearabledata.h"  const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0); -LLAvatarAppearance::LLAvatarAppearance() : +LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :  	LLCharacter(), +	mIsDummy(FALSE),  	mTexSkinColor( NULL ),  	mTexHairColor( NULL ),  	mTexEyeColor( NULL ), -	mIsDummy(FALSE) +	mWearableData(wearable_data)  { +	llassert(mWearableData);  }  // virtual @@ -51,6 +54,17 @@ LLAvatarAppearance::~LLAvatarAppearance()  using namespace LLAvatarAppearanceDefines; +// virtual +BOOL LLAvatarAppearance::isValid() const +{ +	// This should only be called on ourself. +	if (!isSelf()) +	{ +		llerrs << "Called LLAvatarAppearance::isValid() on when isSelf() == false" << llendl; +	} +	return TRUE; +} +  //static  BOOL LLAvatarAppearance::teToColorParams( ETextureIndex te, U32 *param_name )  { @@ -178,5 +192,47 @@ LLColor4 LLAvatarAppearance::getGlobalColor( const std::string& color_name ) con  	}  } +// Unlike most wearable functions, this works for both self and other. +// virtual +BOOL LLAvatarAppearance::isWearingWearableType(LLWearableType::EType type) const +{ +	if (mIsDummy) return TRUE; + +	switch(type) +	{ +		case LLWearableType::WT_SHAPE: +		case LLWearableType::WT_SKIN: +		case LLWearableType::WT_HAIR: +		case LLWearableType::WT_EYES: +			return TRUE;  // everyone has all bodyparts +		default: +			break; // Do nothing +	} + +	/* switch(type) +		case LLWearableType::WT_SHIRT: +			indicator_te = TEX_UPPER_SHIRT; */ +	for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); +		 tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); +		 ++tex_iter) +	{ +		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second; +		if (texture_dict->mWearableType == type) +		{ +			// If you're checking another avatar's clothing, you don't have component textures. +			// Thus, you must check to see if the corresponding baked texture is defined. +			// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing +			// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that +			// gets baked into a texture that always exists (upper or lower). +			if (texture_dict->mIsUsedByBakedTexture) +			{ +				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; +				return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex); +			} +			return FALSE; +		} +	} +	return FALSE; +} diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 0e746b3b9d..2209ede927 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -33,6 +33,7 @@  class LLTexLayerSet;  class LLTexGlobalColor; +class LLWearableData;  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // LLAvatarAppearance @@ -47,9 +48,12 @@ class LLAvatarAppearance : public LLCharacter   **                                                                            **   **                    INITIALIZATION   **/ +private: +	// Hide default constructor. +	LLAvatarAppearance() {}  public: -	LLAvatarAppearance(); +	LLAvatarAppearance(LLWearableData* wearable_data);  	virtual ~LLAvatarAppearance();  /**                    Initialization @@ -62,6 +66,7 @@ public:   **/  public:  	virtual bool 	isSelf() const { return false; } // True if this avatar is for this viewer's agent +	virtual BOOL	isValid() const;  	virtual BOOL	isUsingBakedTextures() const = 0;  /**                    State @@ -145,15 +150,13 @@ public:   **/  public: -	virtual BOOL			isWearingWearableType(LLWearableType::EType type ) const = 0; - -	virtual U32				getWearableCount(const LLWearableType::EType type) const = 0; -	virtual U32				getWearableCount(const U32 tex_index) const = 0; - -	virtual LLWearable*			getWearable(const LLWearableType::EType type, U32 index /*= 0*/) = 0; -	virtual const LLWearable* 	getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const = 0; - +	LLWearableData*			getWearableData() { return mWearableData; } +	const LLWearableData*	getWearableData() const { return mWearableData; } +	virtual BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index = 0 ) const = 0; +	virtual BOOL			isWearingWearableType(LLWearableType::EType type ) const; +private: +	LLWearableData* mWearableData;  };  #endif // LL_AVATAR_APPEARANCE_H diff --git a/indra/newview/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp index 5abf72d51f..1092b525d0 100644 --- a/indra/newview/lldriverparam.cpp +++ b/indra/llappearance/lldriverparam.cpp @@ -24,22 +24,20 @@   * $/LicenseInfo$   */ -#include "llviewerprecompiledheaders.h" +#include "linden_common.h"  #include "lldriverparam.h" -#include "llfasttimer.h" -#include "llvoavatar.h" -#include "llvoavatarself.h" -#include "llagent.h" -#include "llviewerwearable.h" -#include "llagentwearables.h" +#include "llavatarappearance.h" +#include "llwearable.h" +#include "llwearabledata.h"  //-----------------------------------------------------------------------------  // LLDriverParamInfo  //----------------------------------------------------------------------------- -LLDriverParamInfo::LLDriverParamInfo() +LLDriverParamInfo::LLDriverParamInfo() : +	mDriverParam(NULL)  {  } @@ -112,12 +110,14 @@ void LLDriverParamInfo::toStream(std::ostream &out)  	out << std::endl; -	if(isAgentAvatarValid()) +	if(mDriverParam && mDriverParam->getAvatarAppearance()->isSelf() && +		mDriverParam->getAvatarAppearance()->isValid())  	{  		for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)  		{  			LLDrivenEntryInfo driven = *iter; -			LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID); +			LLViewerVisualParam *param =  +				(LLViewerVisualParam*)mDriverParam->getAvatarAppearance()->getVisualParam(driven.mDrivenID);  			if (param)  			{  				param->getInfo()->toStream(out); @@ -139,7 +139,9 @@ void LLDriverParamInfo::toStream(std::ostream &out)  			}  			else  			{ -				llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp.get() << " for driver parameter " << getID() << llendl; +				llwarns << "could not get parameter " << driven.mDrivenID << " from avatar "  +						<< mDriverParam->getAvatarAppearance()  +						<< " for driver parameter " << getID() << llendl;  			}  			out << std::endl;  		} @@ -150,19 +152,16 @@ void LLDriverParamInfo::toStream(std::ostream &out)  // LLDriverParam  //----------------------------------------------------------------------------- -LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :  +LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) :  	mCurrentDistortionParam( NULL ),  -	mAvatarp(avatarp),  -	mWearablep(NULL) -{ -	mDefaultVec.clear(); -} - -LLDriverParam::LLDriverParam(LLWearable *wearablep) :  -	mCurrentDistortionParam( NULL ),  -	mAvatarp(NULL),  -	mWearablep(wearablep) +	mAvatarAppearance(appearance),  +	mWearablep(wearable)  { +	llassert(mAvatarAppearance); +	if (mWearablep) +	{ +		llassert(mAvatarAppearance->isSelf()); +	}  	mDefaultVec.clear();  } @@ -177,67 +176,21 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)  		return FALSE;  	mInfo = info;  	mID = info->mID; +	info->mDriverParam = this;  	setWeight(getDefaultWeight(), FALSE );  	return TRUE;  } -void LLDriverParam::setWearable(LLWearable *wearablep) -{ -	if (wearablep) -	{ -		mWearablep = wearablep; -		mAvatarp = NULL; -	} -} - -void LLDriverParam::setAvatar(LLVOAvatar *avatarp) -{ -	if (avatarp) -	{ -		mWearablep = NULL; -		mAvatarp = avatarp; -	} -} -  /*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const  { -	LLDriverParam *new_param; -	if (wearable) -	{ -		new_param = new LLDriverParam(wearable); -	} -	else -	{ -		if (mWearablep) -		{ -			new_param = new LLDriverParam(mWearablep); -		} -		else -		{ -			new_param = new LLDriverParam(mAvatarp); -		} -	} +	llassert(wearable); +	LLDriverParam *new_param = new LLDriverParam(mAvatarAppearance, wearable);  	*new_param = *this;  	return new_param;  } -#if 0 // obsolete -BOOL LLDriverParam::parseData(LLXmlTreeNode* node) -{ -	LLDriverParamInfo* info = new LLDriverParamInfo; - -	info->parseXml(node); -	if (!setInfo(info)) -	{ -		delete info; -		return FALSE; -	} -	return TRUE; -} -#endif -  void LLDriverParam::setWeight(F32 weight, BOOL upload_bake)  {  	F32 min_weight = getMinWeight(); @@ -456,6 +409,20 @@ const LLVector4a*	LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly  	return v;  }; +S32 LLDriverParam::getDrivenParamsCount() const +{ +	return mDriven.size(); +} + +const LLViewerVisualParam* LLDriverParam::getDrivenParam(S32 index) const +{ +	if (0 > index || index >= mDriven.size()) +	{ +		return NULL; +	} +	return mDriven[index].mParam; +} +  //-----------------------------------------------------------------------------  // setAnimationTarget()  //----------------------------------------------------------------------------- @@ -555,7 +522,7 @@ void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)  		// Thus this wearable needs to get updates from the driver wearable.  		// The call to setVisualParamWeight seems redundant, but is necessary  		// as the number of driven wearables has changed since the last update. -Nyx -		LLWearable *wearable = gAgentWearables.getTopWearable(driver_type); +		LLWearable *wearable = mAvatarAppearance->getWearableData()->getTopWearable(driver_type);  		if (wearable)  		{  			wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false); @@ -624,12 +591,12 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight  void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)  {  	bool use_self = false; -	if(isAgentAvatarValid() && -		mWearablep &&  +	if(mWearablep && +		mAvatarAppearance->isValid() &&  		driven->mParam->getCrossWearable())  	{ -		LLViewerWearable* wearable = dynamic_cast<LLViewerWearable*> (mWearablep); -		if (wearable->isOnTop()) +		LLWearable* wearable = dynamic_cast<LLWearable*> (mWearablep); +		if (mAvatarAppearance->getWearableData()->isOnTop(wearable))  		{  			use_self = true;  		} @@ -638,7 +605,7 @@ void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bo  	if (use_self)  	{  		// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values -		gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake ); +		mAvatarAppearance->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );  	}  	else  	{ diff --git a/indra/newview/lldriverparam.h b/indra/llappearance/lldriverparam.h index 7a4d711d4e..30e71daad9 100644 --- a/indra/newview/lldriverparam.h +++ b/indra/llappearance/lldriverparam.h @@ -30,8 +30,8 @@  #include "llviewervisualparam.h"  #include "llwearabletype.h" -class LLPhysicsMotion; -class LLVOAvatar; +class LLAvatarAppearance; +class LLDriverParam;  class LLWearable;  //----------------------------------------------------------------------------- @@ -71,16 +71,18 @@ public:  protected:  	typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;  	entry_info_list_t mDrivenInfoList; +	LLDriverParam* mDriverParam; // backpointer  };  //-----------------------------------------------------------------------------  class LLDriverParam : public LLViewerVisualParam  { -	friend class LLPhysicsMotion; // physics motion needs to access driven params directly. +private: +	// Hide the default constructor.  Force construction with LLAvatarAppearance. +	LLDriverParam() {}  public: -	LLDriverParam(LLVOAvatar *avatarp); -	LLDriverParam(LLWearable *wearablep); +	LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable = NULL);  	~LLDriverParam();  	// Special: These functions are overridden by child classes @@ -88,14 +90,14 @@ public:  	//   This sets mInfo and calls initialization functions  	BOOL					setInfo(LLDriverParamInfo *info); -	void					setWearable(LLWearable *wearablep); -	void					setAvatar(LLVOAvatar *avatarp); +	LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; } +	const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; } +  	void					updateCrossDrivenParams(LLWearableType::EType driven_type);  	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;  	// LLVisualParam Virtual functions -	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node);  	/*virtual*/ void				apply( ESex sex ) {} // apply is called separately for each driven param.  	/*virtual*/ void				setWeight(F32 weight, BOOL upload_bake);  	/*virtual*/ void				setAnimationTarget( F32 target_value, BOOL upload_bake ); @@ -111,6 +113,9 @@ public:  	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);  	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); +	S32								getDrivenParamsCount() const; +	const LLViewerVisualParam*		getDrivenParam(S32 index) const; +  protected:  	F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);  	void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake); @@ -121,7 +126,7 @@ protected:  	entry_list_t mDriven;  	LLViewerVisualParam* mCurrentDistortionParam;  	// Backlink only; don't make this an LLPointer. -	LLVOAvatar* mAvatarp; +	LLAvatarAppearance* mAvatarAppearance;  	LLWearable* mWearablep;  }; diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index a741a83af7..9b70f737a0 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -40,6 +40,7 @@  #include "lltexturemanagerbridge.h"  #include "llui.h"  #include "llwearable.h" +#include "llwearabledata.h"  #include "llvertexbuffer.h"  #include "llviewervisualparam.h" @@ -1560,11 +1561,11 @@ U32 LLTexLayerTemplate::updateWearableCache() const  		return 0;  	}  	LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te); -	U32 num_wearables = getAvatarAppearance()->getWearableCount(wearable_type); +	U32 num_wearables = getAvatarAppearance()->getWearableData()->getWearableCount(wearable_type);  	U32 added = 0;  	for (U32 i = 0; i < num_wearables; i++)  	{ -		LLWearable*  wearable = getAvatarAppearance()->getWearable(wearable_type, i); +		LLWearable*  wearable = getAvatarAppearance()->getWearableData()->getWearable(wearable_type, i);  		if (!wearable)  		{  			continue; diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index 8a99debac8..e1cd26bdef 100644 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -33,6 +33,7 @@  #include "llwearabletype.h"  #include "lllocaltextureobject.h" +class LLMD5;  class LLVisualParam;  class LLTexGlobalColorInfo;  class LLTexGlobalColor; @@ -98,6 +99,12 @@ public:  	typedef std::map<S32, LLUUID> texture_id_map_t;  	const texture_id_map_t& getTextureIDMap() const { return mTextureIDMap; } +	// Something happened that requires the wearable to be updated (e.g. worn/unworn). +	virtual void		setUpdated() const = 0; + +	// Update the baked texture hash. +	virtual void		addToBakedTextureHash(LLMD5& hash) const = 0; +  protected:  	virtual void 	createVisualParams() = 0; diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp new file mode 100644 index 0000000000..d70bbf286a --- /dev/null +++ b/indra/llappearance/llwearabledata.cpp @@ -0,0 +1,353 @@ +/**  + * @file llwearabledata.cpp + * @brief LLWearableData class implementation + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * 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. + *  + * 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. + *  + * 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 + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llwearabledata.h" + +#include "llavatarappearance.h" +#include "llavatarappearancedefines.h" +#include "lldriverparam.h" +#include "llmd5.h" + +LLWearableData::LLWearableData() : +	mAvatarAppearance(NULL) +{ +} + +// virtual +LLWearableData::~LLWearableData() +{ +} + +using namespace LLAvatarAppearanceDefines; + +LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) +{ +	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); +	if (wearable_iter == mWearableDatas.end()) +	{ +		return NULL; +	} +	wearableentry_vec_t& wearable_vec = wearable_iter->second; +	if (index>=wearable_vec.size()) +	{ +		return NULL; +	} +	else +	{ +		return wearable_vec[index]; +	} +} + +void LLWearableData::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable) +{ +	LLWearable *old_wearable = getWearable(type,index); +	if (!old_wearable) +	{ +		pushWearable(type,wearable); +		return; +	} +	 +	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); +	if (wearable_iter == mWearableDatas.end()) +	{ +		llwarns << "invalid type, type " << type << " index " << index << llendl;  +		return; +	} +	wearableentry_vec_t& wearable_vec = wearable_iter->second; +	if (index>=wearable_vec.size()) +	{ +		llwarns << "invalid index, type " << type << " index " << index << llendl;  +	} +	else +	{ +		wearable_vec[index] = wearable; +		old_wearable->setUpdated(); +		const BOOL removed = FALSE; +		wearableUpdated(wearable, removed); +	} +} + +U32 LLWearableData::pushWearable(const LLWearableType::EType type,  +								   LLWearable *wearable, +								   bool trigger_updated /* = true */) +{ +	if (wearable == NULL) +	{ +		// no null wearables please! +		llwarns << "Null wearable sent for type " << type << llendl; +		return MAX_CLOTHING_PER_TYPE; +	} +	if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) +	{ +		mWearableDatas[type].push_back(wearable); +		if (trigger_updated) +		{ +			const BOOL removed = FALSE; +			wearableUpdated(wearable, removed); +		} +		return mWearableDatas[type].size()-1; +	} +	return MAX_CLOTHING_PER_TYPE; +} + +// virtual +void LLWearableData::wearableUpdated(LLWearable *wearable, BOOL removed) +{ +	wearable->setUpdated(); +	if (!removed) +	{ +		pullCrossWearableValues(wearable->getType()); +	} +} + +void LLWearableData::popWearable(LLWearable *wearable) +{ +	if (wearable == NULL) +	{ +		// nothing to do here. move along. +		return; +	} + +	U32 index = getWearableIndex(wearable); +	const LLWearableType::EType type = wearable->getType(); + +	if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type)) +	{ +		popWearable(type, index); +	} +} + +void LLWearableData::popWearable(const LLWearableType::EType type, U32 index) +{ +	LLWearable *wearable = getWearable(type, index); +	if (wearable) +	{ +		mWearableDatas[type].erase(mWearableDatas[type].begin() + index); +		const BOOL removed = TRUE; +		wearableUpdated(wearable, removed); +	} +} + +void LLWearableData::clearWearableType(const LLWearableType::EType type) +{ +	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); +	if (wearable_iter == mWearableDatas.end()) +	{ +		return; +	} +	wearableentry_vec_t& wearable_vec = wearable_iter->second; +	wearable_vec.clear(); +} + +bool LLWearableData::swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b) +{ +	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); +	if (wearable_iter == mWearableDatas.end()) +	{ +		return false; +	} + +	wearableentry_vec_t& wearable_vec = wearable_iter->second; +	if (0 > index_a || index_a >= wearable_vec.size()) return false; +	if (0 > index_b || index_b >= wearable_vec.size()) return false; + +	LLWearable* wearable = wearable_vec[index_a]; +	wearable_vec[index_a] = wearable_vec[index_b]; +	wearable_vec[index_b] = wearable; +	return true; +} + +void LLWearableData::pullCrossWearableValues(const LLWearableType::EType type) +{ +	llassert(mAvatarAppearance); +	// scan through all of the avatar's visual parameters +	for (LLViewerVisualParam* param = (LLViewerVisualParam*) mAvatarAppearance->getFirstVisualParam();  +		 param; +		 param = (LLViewerVisualParam*) mAvatarAppearance->getNextVisualParam()) +	{ +		if( param ) +		{ +			LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param); +			if(driver_param) +			{ +				// parameter is a driver parameter, have it update its cross-driven params +				driver_param->updateCrossDrivenParams(type); +			} +		} +	} +} + + +U32	LLWearableData::getWearableIndex(const LLWearable *wearable) const +{ +	if (wearable == NULL) +	{ +		return MAX_CLOTHING_PER_TYPE; +	} + +	const LLWearableType::EType type = wearable->getType(); +	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); +	if (wearable_iter == mWearableDatas.end()) +	{ +		llwarns << "tried to get wearable index with an invalid type!" << llendl; +		return MAX_CLOTHING_PER_TYPE; +	} +	const wearableentry_vec_t& wearable_vec = wearable_iter->second; +	for(U32 index = 0; index < wearable_vec.size(); index++) +	{ +		if (wearable_vec[index] == wearable) +		{ +			return index; +		} +	} + +	return MAX_CLOTHING_PER_TYPE; +} + +BOOL LLWearableData::isOnTop(LLWearable* wearable) const +{ +	if (!wearable) return FALSE; +	const LLWearableType::EType type = wearable->getType(); +	return ( getTopWearable(type) == wearable ); +} + +const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) const +{ +	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); +	if (wearable_iter == mWearableDatas.end()) +	{ +		return NULL; +	} +	const wearableentry_vec_t& wearable_vec = wearable_iter->second; +	if (index>=wearable_vec.size()) +	{ +		return NULL; +	} +	else +	{ +		return wearable_vec[index]; +	} +} + +LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) +{ +	U32 count = getWearableCount(type); +	if ( count == 0) +	{ +		return NULL; +	} + +	return getWearable(type, count-1); +} + +const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const +{ +	U32 count = getWearableCount(type); +	if ( count == 0) +	{ +		return NULL; +	} + +	return getWearable(type, count-1); +} + +LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) +{ +	if (getWearableCount(type) == 0) +	{ +		return NULL; +	} + +	return getWearable(type, 0); +} + +const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const +{ +	if (getWearableCount(type) == 0) +	{ +		return NULL; +	} + +	return getWearable(type, 0); +} + +U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const +{ +	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); +	if (wearable_iter == mWearableDatas.end()) +	{ +		return 0; +	} +	const wearableentry_vec_t& wearable_vec = wearable_iter->second; +	return wearable_vec.size(); +} + +U32 LLWearableData::getWearableCount(const U32 tex_index) const +{ +	const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index); +	return getWearableCount(wearable_type); +} + +LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index, +												 BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache +{ +	LLUUID hash_id; +	bool hash_computed = false; +	LLMD5 hash; +	const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index); + +	for (U8 i=0; i < baked_dict->mWearables.size(); i++) +	{ +		const LLWearableType::EType baked_type = baked_dict->mWearables[i]; +		const U32 num_wearables = getWearableCount(baked_type); +		for (U32 index = 0; index < num_wearables; ++index) +		{ +			const LLWearable* wearable = getWearable(baked_type,index); +			if (wearable) +			{ +				wearable->addToBakedTextureHash(hash); +				hash_computed = true; +			} +		} +	} +	if (hash_computed) +	{ +		hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES); + +		if (!generate_valid_hash) +		{ +			invalidateBakedTextureHash(hash); +		} +		hash.finalize(); +		hash.raw_digest(hash_id.mData); +	} + +	return hash_id; +} + + diff --git a/indra/llappearance/llwearabledata.h b/indra/llappearance/llwearabledata.h new file mode 100644 index 0000000000..2931424131 --- /dev/null +++ b/indra/llappearance/llwearabledata.h @@ -0,0 +1,108 @@ +/**  + * @file llwearabledata.h + * @brief LLWearableData class header file + * + * $LicenseInfo:firstyear=20012license=viewerlgpl$ + * Second Life Viewer Source Code + * 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. + *  + * 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. + *  + * 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 + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_WEARABLEDATA_H +#define LL_WEARABLEDATA_H + +#include "llavatarappearancedefines.h" +#include "llerror.h" + +class LLAvatarAppearance; + +class LLWearableData +{ +	// *TODO: Figure out why this is causing compile error. +	//LOG_CLASS(LLWearableData); + +	//-------------------------------------------------------------------- +	// Constructors / destructors / Initializers +	//-------------------------------------------------------------------- +public: +	LLWearableData(); +	virtual ~LLWearableData(); + +	void setAvatarAppearance(LLAvatarAppearance* appearance) { mAvatarAppearance = appearance; } + +protected: +	//-------------------------------------------------------------------- +	// Accessors +	//-------------------------------------------------------------------- +public: +	LLWearable*			getWearable(const LLWearableType::EType type, U32 index /*= 0*/);  +	const LLWearable* 	getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const; +	LLWearable*			getTopWearable(const LLWearableType::EType type); +	const LLWearable*	getTopWearable(const LLWearableType::EType type) const; +	LLWearable*			getBottomWearable(const LLWearableType::EType type); +	const LLWearable*	getBottomWearable(const LLWearableType::EType type) const; +	U32				getWearableCount(const LLWearableType::EType type) const; +	U32				getWearableCount(const U32 tex_index) const; +	U32				getWearableIndex(const LLWearable *wearable) const; + +	BOOL			isOnTop(LLWearable* wearable) const; + +	static const U32 MAX_CLOTHING_PER_TYPE = 5;  + +	//-------------------------------------------------------------------- +	// Setters +	//-------------------------------------------------------------------- +protected: +	// Low-level data structure setter - public access is via setWearableItem, etc. +	void 			setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable); +	U32 			pushWearable(const LLWearableType::EType type, LLWearable *wearable,  +								 bool trigger_updated = true); +	virtual void	wearableUpdated(LLWearable *wearable, BOOL removed); +	void 			popWearable(LLWearable *wearable); +	void			popWearable(const LLWearableType::EType type, U32 index); +	void			clearWearableType(const LLWearableType::EType type); +	bool			swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b); + +private: +	void			pullCrossWearableValues(const LLWearableType::EType type); + +	//-------------------------------------------------------------------- +	// Server Communication +	//-------------------------------------------------------------------- +public: +	LLUUID			computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index, +											BOOL generate_valid_hash = TRUE); +protected: +	virtual void	invalidateBakedTextureHash(LLMD5& hash) const {} + +	//-------------------------------------------------------------------- +	// Member variables +	//-------------------------------------------------------------------- +private: +	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; + +}; + + + +#endif // LL_WEARABLEDATA_H + diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 0a6a8f9fa6..85cf1cd3f5 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -286,7 +286,7 @@ void LLCharacter::removeAnimationData(std::string name)  //-----------------------------------------------------------------------------  // setVisualParamWeight()  //----------------------------------------------------------------------------- -BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL upload_bake) +BOOL LLCharacter::setVisualParamWeight(const LLVisualParam* which_param, F32 weight, BOOL upload_bake)  {  	S32 index = which_param->getID();  	visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 3ebb2bffb0..2f2b2405b6 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -197,7 +197,7 @@ public:  	void addVisualParam(LLVisualParam *param);  	void addSharedVisualParam(LLVisualParam *param); -	virtual BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE ); +	virtual BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );  	virtual BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );  	virtual BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE ); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 214071fa67..21b1512e58 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -158,7 +158,6 @@ set(viewer_SOURCE_FILES      lldrawpooltree.cpp      lldrawpoolwater.cpp      lldrawpoolwlsky.cpp -    lldriverparam.cpp      lldynamictexture.cpp      llemote.cpp      llenvmanager.cpp @@ -728,7 +727,6 @@ set(viewer_HEADER_FILES      lldrawpooltree.h      lldrawpoolwater.h      lldrawpoolwlsky.h -    lldriverparam.h      lldynamictexture.h      llemote.h      llenvmanager.h diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 08238e1aea..40cedc1b35 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -119,7 +119,7 @@ void LLAgentWearables::dump()  		llinfos << "Type: " << i << " count " << count << llendl;  		for (U32 j=0; j<count; j++)  		{ -			LLViewerWearable* wearable = getWearable((LLWearableType::EType)i,j); +			LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)i,j);  			if (wearable == NULL)  			{  				llinfos << "    " << j << " NULL wearable" << llendl; @@ -159,6 +159,7 @@ struct LLAgentDumper  };  LLAgentWearables::LLAgentWearables() : +	LLWearableData(),  	mWearablesLoaded(FALSE)  ,	mCOFChangeInProgress(false)  { @@ -182,12 +183,11 @@ void LLAgentWearables::initClass()  }  void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) -{  -	if (avatar) -	{ -		avatar->outputRezTiming("Sending wearables request"); -		sendAgentWearablesRequest(); -	} +{ +	llassert(avatar); +	avatar->outputRezTiming("Sending wearables request"); +	sendAgentWearablesRequest(); +	setAvatarAppearance(avatar);  }  // wearables @@ -312,7 +312,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()  	{  		for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index)  		{ -			LLViewerWearable* wearable = getWearable((LLWearableType::EType)type,index); +			LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type,index);  			if (wearable)  			{  				if (wearable->getItemID().isNull()) @@ -354,7 +354,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()  		U8 type_u8 = (U8)type;  		gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8); -		LLViewerWearable* wearable = getWearable((LLWearableType::EType)type, 0); +		LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type, 0);  		if (wearable)  		{  			//llinfos << "Sending wearable " << wearable->getName() << llendl; @@ -382,7 +382,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()  void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update,  									const std::string new_name)  { -	LLViewerWearable* old_wearable = getWearable(type, index); +	LLViewerWearable* old_wearable = getViewerWearable(type, index);  	if(!old_wearable) return;  	bool name_changed = !new_name.empty() && (new_name != old_wearable->getName());  	if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion()) @@ -465,7 +465,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,  		llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;  		return;  	} -	LLViewerWearable* old_wearable = getWearable(type, index); +	LLViewerWearable* old_wearable = getViewerWearable(type, index);  	if (!old_wearable)  	{  		llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl; @@ -518,7 +518,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,  void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index)  { -	LLViewerWearable* wearable = getWearable(type, index); +	LLViewerWearable* wearable = getViewerWearable(type, index);  	llassert(wearable);  	if (wearable)  	{ @@ -553,7 +553,7 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string&  			LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j);  			if (curr_item_id == item_id)  			{ -				LLViewerWearable* old_wearable = getWearable((LLWearableType::EType)i,j); +				LLViewerWearable* old_wearable = getViewerWearable((LLWearableType::EType)i,j);  				llassert(old_wearable);  				if (!old_wearable) continue; @@ -647,7 +647,7 @@ const LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& it  	{  		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)  		{ -			const LLViewerWearable * curr_wearable = getWearable((LLWearableType::EType)i, j); +			const LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);  			if (curr_wearable && (curr_wearable->getItemID() == base_item_id))  			{  				return curr_wearable; @@ -664,7 +664,7 @@ LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)  	{  		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)  		{ -			LLViewerWearable * curr_wearable = getWearable((LLWearableType::EType)i, j); +			LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);  			if (curr_wearable && (curr_wearable->getItemID() == base_item_id))  			{  				return curr_wearable; @@ -680,7 +680,7 @@ LLViewerWearable*	LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_i  	{  		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)  		{ -			LLViewerWearable * curr_wearable = getWearable((LLWearableType::EType)i, j); +			LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);  			if (curr_wearable && (curr_wearable->getAssetID() == asset_id))  			{  				return curr_wearable; @@ -699,215 +699,55 @@ void LLAgentWearables::sendAgentWearablesRequest()  	gAgent.sendReliableMessage();  } -// static -BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type) +LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/)  { -	return (gAgentWearables.getWearableCount(type) > 0); +	return dynamic_cast<LLViewerWearable*> (getWearable(type, index));  } -LLViewerWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) +const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const  { -	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); -	if (wearable_iter == mWearableDatas.end()) -	{ -		return NULL; -	} -	wearableentry_vec_t& wearable_vec = wearable_iter->second; -	if (index>=wearable_vec.size()) -	{ -		return NULL; -	} -	else -	{ -		return wearable_vec[index]; -	} +	return dynamic_cast<const LLViewerWearable*> (getWearable(type, index));  } -void LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index, LLViewerWearable *wearable) -{ - -	LLViewerWearable *old_wearable = getWearable(type,index); -	if (!old_wearable) -	{ -		pushWearable(type,wearable); -		return; -	} -	 -	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); -	if (wearable_iter == mWearableDatas.end()) -	{ -		llwarns << "invalid type, type " << type << " index " << index << llendl;  -		return; -	} -	wearableentry_vec_t& wearable_vec = wearable_iter->second; -	if (index>=wearable_vec.size()) -	{ -		llwarns << "invalid index, type " << type << " index " << index << llendl;  -	} -	else -	{ -		wearable_vec[index] = wearable; -		old_wearable->setLabelUpdated(); -		wearableUpdated(wearable); -		checkWearableAgainstInventory(wearable); -	} -} - -U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLViewerWearable *wearable) -{ -	if (wearable == NULL) -	{ -		// no null wearables please! -		llwarns << "Null wearable sent for type " << type << llendl; -		return MAX_CLOTHING_PER_TYPE; -	} -	if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) -	{ -		mWearableDatas[type].push_back(wearable); -		wearableUpdated(wearable); -		checkWearableAgainstInventory(wearable); -		return mWearableDatas[type].size()-1; -	} -	return MAX_CLOTHING_PER_TYPE; -} - -void LLAgentWearables::wearableUpdated(LLViewerWearable *wearable) +// static +BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)  { -	gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE); -	wearable->refreshName(); -	wearable->setLabelUpdated(); - -	wearable->pullCrossWearableValues(); - -	// Hack pt 2. If the wearable we just loaded has definition version 24, -	// then force a re-save of this wearable after slamming the version number to 22. -	// This number was incorrectly incremented for internal builds before release, and -	// this fix will ensure that the affected wearables are re-saved with the right version number. -	// the versions themselves are compatible. This code can be removed before release. -	if( wearable->getDefinitionVersion() == 24 ) -	{ -		wearable->setDefinitionVersion(22); -		U32 index = getWearableIndex(wearable); -		llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl; -		saveWearable(wearable->getType(),index,TRUE); -	} - +	return (gAgentWearables.getWearableCount(type) > 0);  } -void LLAgentWearables::popWearable(LLViewerWearable *wearable) +// virtual +void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)  { -	if (wearable == NULL) -	{ -		// nothing to do here. move along. -		return; -	} - -	U32 index = getWearableIndex(wearable); -	LLWearableType::EType type = wearable->getType(); - -	if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type)) +	if (isAgentAvatarValid())  	{ -		popWearable(type, index); +		const BOOL upload_result = removed; +		gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result);  	} -} -void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index) -{ -	LLViewerWearable *wearable = getWearable(type, index); -	if (wearable) -	{ -		mWearableDatas[type].erase(mWearableDatas[type].begin() + index); -		if (isAgentAvatarValid()) -		{ -		gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE); -		} -		wearable->setLabelUpdated(); -	} -} +	LLWearableData::wearableUpdated(wearable, removed); -U32	LLAgentWearables::getWearableIndex(const LLViewerWearable *wearable) const -{ -	if (wearable == NULL) +	if (!removed)  	{ -		return MAX_CLOTHING_PER_TYPE; -	} +		LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable); +		viewer_wearable->refreshName(); -	const LLWearableType::EType type = wearable->getType(); -	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); -	if (wearable_iter == mWearableDatas.end()) -	{ -		llwarns << "tried to get wearable index with an invalid type!" << llendl; -		return MAX_CLOTHING_PER_TYPE; -	} -	const wearableentry_vec_t& wearable_vec = wearable_iter->second; -	for(U32 index = 0; index < wearable_vec.size(); index++) -	{ -		if (wearable_vec[index] == wearable) +		// Hack pt 2. If the wearable we just loaded has definition version 24, +		// then force a re-save of this wearable after slamming the version number to 22. +		// This number was incorrectly incremented for internal builds before release, and +		// this fix will ensure that the affected wearables are re-saved with the right version number. +		// the versions themselves are compatible. This code can be removed before release. +		if( wearable->getDefinitionVersion() == 24 )  		{ -			return index; +			wearable->setDefinitionVersion(22); +			U32 index = getWearableIndex(wearable); +			llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl; +			saveWearable(wearable->getType(),index,TRUE);  		} -	} - -	return MAX_CLOTHING_PER_TYPE; -} -const LLViewerWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) const -{ -	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); -	if (wearable_iter == mWearableDatas.end()) -	{ -		return NULL; -	} -	const wearableentry_vec_t& wearable_vec = wearable_iter->second; -	if (index>=wearable_vec.size()) -	{ -		return NULL; -	} -	else -	{ -		return wearable_vec[index]; +		checkWearableAgainstInventory(viewer_wearable);  	}  } -LLViewerWearable* LLAgentWearables::getTopWearable(const LLWearableType::EType type) -{ -	U32 count = getWearableCount(type); -	if ( count == 0) -	{ -		return NULL; -	} - -	return getWearable(type, count-1); -} - -LLViewerWearable* LLAgentWearables::getBottomWearable(const LLWearableType::EType type) -{ -	if (getWearableCount(type) == 0) -	{ -		return NULL; -	} - -	return getWearable(type, 0); -} - -U32 LLAgentWearables::getWearableCount(const LLWearableType::EType type) const -{ -	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); -	if (wearable_iter == mWearableDatas.end()) -	{ -		return 0; -	} -	const wearableentry_vec_t& wearable_vec = wearable_iter->second; -	return wearable_vec.size(); -} - -U32 LLAgentWearables::getWearableCount(const U32 tex_index) const -{ -	const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index); -	return getWearableCount(wearable_type); -} - -  BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const  {  	return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end(); @@ -920,7 +760,7 @@ U32 LLAgentWearables::itemUpdatePendingCount() const  const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const  { -	const LLViewerWearable *wearable = getWearable(type,index); +	const LLViewerWearable *wearable = getViewerWearable(type,index);  	if (wearable)  		return wearable->getItemID();  	else @@ -929,7 +769,7 @@ const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32  const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const  { -	const LLViewerWearable *wearable = getWearable(type,index); +	const LLViewerWearable *wearable = getViewerWearable(type,index);  	if (wearable)  		return wearable->getAssetID();  	else @@ -1095,7 +935,7 @@ void LLAgentWearables::recoverMissingWearableDone()  void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index)  { -	LLViewerWearable* wearable = getWearable((LLWearableType::EType)wearable_type, wearable_index); +	LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)wearable_type, wearable_index);  	if (!wearable)  	{  		llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl; @@ -1305,7 +1145,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_  	}  	else  	{ -		LLViewerWearable* old_wearable = getWearable(type,index); +		LLViewerWearable* old_wearable = getViewerWearable(type,index);  		if (old_wearable)  		{ @@ -1360,10 +1200,10 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo  	//LLAgentDumper dumper("removeWearable");  	if (do_remove_all)  	{ -		S32 max_entry = mWearableDatas[type].size()-1; +		S32 max_entry = getWearableCount(type)-1;  		for (S32 i=max_entry; i>=0; i--)  		{ -			LLViewerWearable* old_wearable = getWearable(type,i); +			LLViewerWearable* old_wearable = getViewerWearable(type,i);  			//queryWearableCache(); // moved below  			if (old_wearable)  			{ @@ -1371,11 +1211,11 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo  				old_wearable->removeFromAvatar(TRUE);  			}  		} -		mWearableDatas[type].clear(); +		clearWearableType(type);  	}  	else  	{ -		LLViewerWearable* old_wearable = getWearable(type, index); +		LLViewerWearable* old_wearable = getViewerWearable(type, index);  		//queryWearableCache(); // moved below  		if (old_wearable) @@ -1439,8 +1279,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  			{  				pushWearable(type,new_wearable);  			} -			wearableUpdated(new_wearable); -			checkWearableAgainstInventory(new_wearable); +			const BOOL removed = FALSE; +			wearableUpdated(new_wearable, removed);  		}  	} @@ -1491,7 +1331,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearab  	{  		// Remove old wearable, if any  		// MULTI_WEARABLE: hardwired to 0 -		LLViewerWearable* old_wearable = getWearable(type,0); +		LLViewerWearable* old_wearable = getViewerWearable(type,0);  		if (old_wearable)  		{  			const LLUUID& old_item_id = old_wearable->getItemID(); @@ -1560,9 +1400,10 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWeara  	if (do_append && getWearableItemID(type,0).notNull())  	{  		new_wearable->setItemID(new_item->getUUID()); -		mWearableDatas[type].push_back(new_wearable); +		const bool trigger_updated = false; +		pushWearable(type, new_wearable, trigger_updated);  		llinfos << "Added additional wearable for type " << type -				<< " size is now " << mWearableDatas[type].size() << llendl; +				<< " size is now " << getWearableCount(type) << llendl;  		checkWearableAgainstInventory(new_wearable);  	}  	else @@ -1570,7 +1411,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWeara  		// Replace the old wearable with a new one.  		llassert(new_item->getAssetUUID() == new_wearable->getAssetID()); -		LLViewerWearable *old_wearable = getWearable(type,0); +		LLViewerWearable *old_wearable = getViewerWearable(type,0);  		LLUUID old_item_id;  		if (old_wearable)  		{ @@ -1585,7 +1426,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWeara  			gInventory.notifyObservers();  		}  		llinfos << "Replaced current element 0 for type " << type -				<< " size is now " << mWearableDatas[type].size() << llendl; +				<< " size is now " << getWearableCount(type) << llendl;  	}  	//llinfos << "LLVOAvatar::setWearableItem()" << llendl; @@ -1652,46 +1493,14 @@ void LLAgentWearables::queryWearableCache()  	}  } -LLUUID LLAgentWearables::computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index, -												 BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache +// virtual +void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const  { -	LLUUID hash_id; -	bool hash_computed = false; -	LLMD5 hash; -	const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index); - -	for (U8 i=0; i < baked_dict->mWearables.size(); i++) -	{ -		const LLWearableType::EType baked_type = baked_dict->mWearables[i]; -		const U32 num_wearables = getWearableCount(baked_type); -		for (U32 index = 0; index < num_wearables; ++index) -		{ -			const LLViewerWearable* wearable = getWearable(baked_type,index); -			if (wearable) -			{ -				LLUUID asset_id = wearable->getAssetID(); -				hash.update((const unsigned char*)asset_id.mData, UUID_BYTES); -				hash_computed = true; -			} -		} -	} -	if (hash_computed) +	// Add some garbage into the hash so that it becomes invalid. +	if (isAgentAvatarValid())  	{ -		hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES); - -		// Add some garbage into the hash so that it becomes invalid. -		if (!generate_valid_hash) -		{ -			if (isAgentAvatarValid()) -			{ -				hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES); -			} -		} -		hash.finalize(); -		hash.raw_digest(hash_id.mData); +		hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);  	} - -	return hash_id;  }  // User has picked "remove from avatar" from a menu. @@ -1875,13 +1684,13 @@ void LLAgentWearables::checkWearablesLoaded() const  // Returns false if the given wearable is already topmost/bottommost  // (depending on closer_to_body parameter). -bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) +bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) const  { -	const LLViewerWearable* wearable = getWearableFromItemID(item_id); +	const LLWearable* wearable = getWearableFromItemID(item_id);  	if (!wearable) return false;  	LLWearableType::EType wtype = wearable->getType(); -	const LLViewerWearable* marginal_wearable = closer_to_body ? getBottomWearable(wtype) : getTopWearable(wtype); +	const LLWearable* marginal_wearable = closer_to_body ? getBottomWearable(wtype) : getTopWearable(wtype);  	if (!marginal_wearable) return false;  	return wearable != marginal_wearable; @@ -1918,7 +1727,7 @@ void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake)  	{  		for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count)  		{ -			LLViewerWearable *wearable = getWearable((LLWearableType::EType)type,count); +			LLViewerWearable *wearable = getViewerWearable((LLWearableType::EType)type,count);  			llassert(wearable);  			if (wearable)  			{ @@ -1933,28 +1742,39 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos  	if (!item) return false;  	if (!item->isWearableType()) return false; -	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(item->getWearableType()); -	if (wearable_iter == mWearableDatas.end()) return false; - -	wearableentry_vec_t& wearable_vec = wearable_iter->second; -	if (wearable_vec.empty()) return false; +	LLWearableType::EType type = item->getWearableType(); +	U32 wearable_count = getWearableCount(type); +	if (0 == wearable_count) return false;  	const LLUUID& asset_id = item->getAssetUUID();  	//nowhere to move if the wearable is already on any boundary (closest to the body/furthest from the body) -	if (closer_to_body && asset_id == wearable_vec.front()->getAssetID()) return false; -	if (!closer_to_body && asset_id == wearable_vec.back()->getAssetID()) return false; +	if (closer_to_body) +	{ +		LLViewerWearable* bottom_wearable = dynamic_cast<LLViewerWearable*>( getBottomWearable(type) ); +		if (bottom_wearable->getAssetID() == asset_id) +		{ +			return false; +		} +	} +	else // !closer_to_body +	{ +		LLViewerWearable* top_wearable = dynamic_cast<LLViewerWearable*>( getTopWearable(type) ); +		if (top_wearable->getAssetID() == asset_id) +		{ +			return false; +		} +	} -	for (U32 i = 0; i < wearable_vec.size(); ++i) +	for (U32 i = 0; i < wearable_count; ++i)  	{ -		LLViewerWearable* wearable = wearable_vec[i]; +		LLViewerWearable* wearable = getViewerWearable(type, i);  		if (!wearable) continue;  		if (wearable->getAssetID() != asset_id) continue;  		//swapping wearables  		U32 swap_i = closer_to_body ? i-1 : i+1; -		wearable_vec[i] = wearable_vec[swap_i]; -		wearable_vec[swap_i] = wearable; +		swapWearables(type, i, swap_i);  		return true;  	} diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 41995dd55b..a60fbc969b 100755 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -37,6 +37,7 @@  #include "llinventorymodel.h"  #include "llviewerinventory.h"  #include "llavatarappearancedefines.h" +#include "llwearabledata.h"  class LLInventoryItem;  class LLVOAvatarSelf; @@ -44,7 +45,7 @@ class LLViewerWearable;  class LLInitialWearablesFetch;  class LLViewerObject; -class LLAgentWearables : public LLInitClass<LLAgentWearables> +class LLAgentWearables : public LLInitClass<LLAgentWearables>, public LLWearableData  {  	//--------------------------------------------------------------------  	// Constructors / destructors / Initializers @@ -78,7 +79,7 @@ public:  	bool			isCOFChangeInProgress() const { return mCOFChangeInProgress; }  	void			updateWearablesLoaded();  	void			checkWearablesLoaded() const; -	bool			canMoveWearable(const LLUUID& item_id, bool closer_to_body); +	bool			canMoveWearable(const LLUUID& item_id, bool closer_to_body) const;  	// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.  	bool			canWearableBeRemoved(const LLViewerWearable* wearable) const; @@ -94,36 +95,22 @@ public:  	const LLViewerWearable*	getWearableFromItemID(const LLUUID& item_id) const;  	LLViewerWearable*	getWearableFromItemID(const LLUUID& item_id);  	LLViewerWearable*	getWearableFromAssetID(const LLUUID& asset_id); +	LLViewerWearable*		getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/);  +	const LLViewerWearable*	getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;  	LLInventoryItem*	getWearableInventoryItem(LLWearableType::EType type, U32 index /*= 0*/);  	static BOOL			selfHasWearable(LLWearableType::EType type); -	LLViewerWearable*			getWearable(const LLWearableType::EType type, U32 index /*= 0*/);  -	const LLViewerWearable* 	getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const; -	LLViewerWearable*		getTopWearable(const LLWearableType::EType type); -	LLViewerWearable*		getBottomWearable(const LLWearableType::EType type); -	U32				getWearableCount(const LLWearableType::EType type) const; -	U32				getWearableCount(const U32 tex_index) const; - -	static const U32 MAX_CLOTHING_PER_TYPE = 5;  -  	//--------------------------------------------------------------------  	// Setters  	//-------------------------------------------------------------------- -  private: -	// Low-level data structure setter - public access is via setWearableItem, etc. -	void 			setWearable(const LLWearableType::EType type, U32 index, LLViewerWearable *wearable); -	U32 			pushWearable(const LLWearableType::EType type, LLViewerWearable *wearable); -	void			wearableUpdated(LLViewerWearable *wearable); -	void 			popWearable(LLViewerWearable *wearable); -	void			popWearable(const LLWearableType::EType type, U32 index); -	 +	/*virtual*/void	wearableUpdated(LLWearable *wearable, BOOL removed);  public:  	void			setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false);  	void			setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove);  	void			setWearableName(const LLUUID& item_id, const std::string& new_name); +	// *TODO: Move this into llappearance/LLWearableData ?  	void			addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index); -	U32				getWearableIndex(const LLViewerWearable *wearable) const;  protected:  	void			setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append = false); @@ -171,10 +158,9 @@ protected:  public:  	// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)  	static void		processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data); -	LLUUID			computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index, -											BOOL generate_valid_hash = TRUE);  protected: +	/*virtual*/ void	invalidateBakedTextureHash(LLMD5& hash) const;  	void			sendAgentWearablesUpdate();  	void			sendAgentWearablesRequest();  	void			queryWearableCache(); @@ -243,10 +229,6 @@ private:  	// Member variables  	//--------------------------------------------------------------------  private: -	typedef std::vector<LLViewerWearable*> 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; -  	static BOOL		mInitialWearablesUpdateReceived;  	BOOL			mWearablesLoaded;  	std::set<LLUUID>	mItemsAwaitingWearableUpdate; diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 68bdf9a8d6..048837acfe 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -82,7 +82,7 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,  		if (avatarp->isSelf())  		{  			const LLWearableType::EType wearable_type = tex_entry->mWearableType; -			LLViewerWearable *wearable = gAgentWearables.getWearable(wearable_type, 0); +			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);  			if (wearable)  			{  				LLLocalTextureObject *lto = wearable->getLocalTextureObject(te); @@ -174,7 +174,7 @@ void LLFloaterAvatarTextures::onClickDump(void* data)  				LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType((ETextureIndex)i);  				if (avatarp->isSelf())  				{ -					LLViewerWearable *wearable = gAgentWearables.getWearable(wearable_type, 0); +					LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);  					if (wearable)  					{  						LLLocalTextureObject *lto = wearable->getLocalTextureObject(i); diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 3a199135b6..834172f58f 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -483,7 +483,7 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp  	U32 count = gAgentWearables.getWearableCount(type);  	for(U32 wearable_iter = 0; wearable_iter < count; wearable_iter++)  	{ -		LLViewerWearable* wearable = gAgentWearables.getWearable(type, wearable_iter); +		LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_iter);  		if (wearable)  		{  			std::vector<LLLocalTextureObject*> texture_list = wearable->getLocalTextureListSeq(); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 9aadca1d80..43bb1f57e0 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -922,7 +922,7 @@ void LLPanelEditWearable::onCommitSexChange()          }          bool is_new_sex_male = (gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE) == SEX_MALE; -        LLViewerWearable*     wearable = gAgentWearables.getWearable(type, index); +        LLViewerWearable*     wearable = gAgentWearables.getViewerWearable(type, index);          if (wearable)          {                  wearable->setVisualParamWeight(param->getID(), is_new_sex_male, FALSE); diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index cb6989c9dd..ded7d66022 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -166,7 +166,7 @@ protected:  		} -        void setParamValue(LLViewerVisualParam *param, +        void setParamValue(const LLViewerVisualParam *param,                             const F32 new_value_local,                                                     F32 behavior_maxeffect); @@ -673,12 +673,10 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)  								 0,  								 FALSE);  			} -			for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); -			     iter != driver_param->mDriven.end(); -			     ++iter) +			S32 num_driven = driver_param->getDrivenParamsCount(); +			for (S32 i = 0; i < num_driven; ++i)  			{ -				LLDrivenEntry &entry = (*iter); -				LLViewerVisualParam *driven_param = entry.mParam; +				const LLViewerVisualParam *driven_param = driver_param->getDrivenParam(i);  				setParamValue(driven_param,position_new_local_clamped, behavior_maxeffect);  			}  		} @@ -758,7 +756,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)  }  // Range of new_value_local is assumed to be [0 , 1] normalized. -void LLPhysicsMotion::setParamValue(LLViewerVisualParam *param, +void LLPhysicsMotion::setParamValue(const LLViewerVisualParam *param,                                      F32 new_value_normalized,  				    F32 behavior_maxeffect)  { diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 6a692209e9..8c4a05b116 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -389,7 +389,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearab  	if (!wearable)  	{ -		wearable = gAgentWearables.getWearable(LLWearableType::WT_SHAPE, 0); +		wearable = gAgentWearables.getViewerWearable(LLWearableType::WT_SHAPE, 0);  	}  	if (!wearable)  	{ diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index 34f24ef330..eb3a212eae 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -632,11 +632,6 @@ void LLViewerWearable::revertValues()  	}  } -BOOL LLViewerWearable::isOnTop() const -{  -	return (this == gAgentWearables.getTopWearable(mType)); -} -  void LLViewerWearable::createLayers(S32 te)  {  	LLViewerTexLayerSet *layer_set = gAgentAvatarp->getLayerSet((ETextureIndex)te); @@ -736,27 +731,8 @@ void LLViewerWearable::destroyTextures()  	mSavedTEMap.clear();  } -void LLViewerWearable::pullCrossWearableValues() -{ -	// scan through all of the avatar's visual parameters -	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();  -		 param; -		 param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam()) -	{ -		if( param ) -		{ -			LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param); -			if(driver_param) -			{ -				// parameter is a driver parameter, have it update its  -				driver_param->updateCrossDrivenParams(getType()); -			} -		} -	} -} - - -void LLViewerWearable::setLabelUpdated() const +// virtual +void LLViewerWearable::setUpdated() const  {   	gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());  } @@ -771,6 +747,13 @@ void LLViewerWearable::refreshName()  	}  } +// virtual +void LLViewerWearable::addToBakedTextureHash(LLMD5& hash) const +{ +	LLUUID asset_id = getAssetID(); +	hash.update((const unsigned char*)asset_id.mData, UUID_BYTES); +} +  struct LLWearableSaveData  {  	LLWearableType::EType mType; diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h index ccc26000f2..b3c1e3c3ba 100644 --- a/indra/newview/llviewerwearable.h +++ b/indra/newview/llviewerwearable.h @@ -86,17 +86,17 @@ public:  	void				revertValues();  	void				saveValues(); -	void				pullCrossWearableValues();		 - -	BOOL				isOnTop() const;  	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn). -	void				setLabelUpdated() const; +	/*virtual*/void		setUpdated() const;  	// the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem,  	// not the wearable asset itself.  	void				refreshName(); +	// Update the baked texture hash. +	/*virtual*/void		addToBakedTextureHash(LLMD5& hash) const; +  protected:  	typedef std::map<S32, LLLocalTextureObject*> te_map_t; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index b86c5d5e8f..2309ea3488 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -644,7 +644,7 @@ static F32 calc_bouncy_animation(F32 x);  LLVOAvatar::LLVOAvatar(const LLUUID& id,  					   const LLPCode pcode,  					   LLViewerRegion* regionp) : -	LLAvatarAppearance(), +	LLAvatarAppearance(&gAgentWearables),  	LLViewerObject(id, pcode, regionp),  	mSpecialRenderMode(0),  	mAttachmentGeometryBytes(0), @@ -5860,30 +5860,6 @@ void LLVOAvatar::updateVisualParams()  	updateHeadOffset();  } -// virtual -U32 LLVOAvatar::getWearableCount(const LLWearableType::EType type) const -{ -	return gAgentWearables.getWearableCount(type); -} - -// virtual -U32 LLVOAvatar::getWearableCount(const U32 tex_index) const -{ -	return gAgentWearables.getWearableCount(tex_index); -} - -// virtual -LLWearable* LLVOAvatar::getWearable(const LLWearableType::EType type, U32 index /*= 0*/) -{ -	return gAgentWearables.getWearable(type, index); -} - -// virtual -const LLWearable* LLVOAvatar::getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const -{ -	return gAgentWearables.getWearable(type, index); -} -  //-----------------------------------------------------------------------------  // isActive()  //----------------------------------------------------------------------------- @@ -7008,48 +6984,6 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const  	}  } -// Unlike most wearable functions, this works for both self and other. -BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const -{ -	if (mIsDummy) return TRUE; - -	switch(type) -	{ -		case LLWearableType::WT_SHAPE: -		case LLWearableType::WT_SKIN: -		case LLWearableType::WT_HAIR: -		case LLWearableType::WT_EYES: -			return TRUE;  // everyone has all bodyparts -		default: -			break; // Do nothing -	} - -	/* switch(type) -		case LLWearableType::WT_SHIRT: -			indicator_te = TEX_UPPER_SHIRT; */ -	for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); -		 tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); -		 ++tex_iter) -	{ -		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second; -		if (texture_dict->mWearableType == type) -		{ -			// If you're checking another avatar's clothing, you don't have component textures. -			// Thus, you must check to see if the corresponding baked texture is defined. -			// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing -			// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that -			// gets baked into a texture that always exists (upper or lower). -			if (texture_dict->mIsUsedByBakedTexture) -			{ -				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; -				return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex); -			} -			return FALSE; -		} -	} -	return FALSE; -} -  //-----------------------------------------------------------------------------  // clampAttachmentPositions()  //----------------------------------------------------------------------------- diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 5f780da145..54719d2671 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -227,17 +227,6 @@ public:  	/*virtual*/BOOL	isUsingBakedTextures() const { return mUseServerBakes; } // e.g. false if in appearance edit mode		  	bool isBuilt() const { return mIsBuilt; } -/******************************************************************************** - **                                                                            ** - **                    WEARABLES - **/ -public: -	/*virtual*/ U32				getWearableCount(const LLWearableType::EType type) const; -	/*virtual*/ U32				getWearableCount(const U32 tex_index) const; - -	/*virtual*/ LLWearable*			getWearable(const LLWearableType::EType type, U32 index /*= 0*/); -	/*virtual*/ const LLWearable* 	getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const; -  private: //aligned members  	LL_ALIGN_16(LLVector4a	mImpostorExtents[2]); @@ -755,9 +744,6 @@ public:   **                    WEARABLES   **/ -public: -	virtual BOOL			isWearingWearableType(LLWearableType::EType type ) const; -	  	//--------------------------------------------------------------------  	// Attachments  	//-------------------------------------------------------------------- diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index e836a5e4a8..c1984fa738 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -74,9 +74,7 @@ LLPointer<LLVOAvatarSelf> gAgentAvatarp = NULL;  BOOL isAgentAvatarValid()  { -	return (gAgentAvatarp.notNull() && -			(gAgentAvatarp->getRegion() != NULL) && -			(!gAgentAvatarp->isDead())); +	return (gAgentAvatarp.notNull() && gAgentAvatarp->isValid());  }  void selfStartPhase(const std::string& phase_name) @@ -670,9 +668,15 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)  }  // virtual +BOOL LLVOAvatarSelf::isValid() const +{ +	return ((getRegion() != NULL) && !isDead()); +} + +// virtual  void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  { -	if (isAgentAvatarValid()) +	if (isValid())  	{  		LLVOAvatar::idleUpdate(agent, world, time);  		idleUpdateTractorBeam(); @@ -695,7 +699,7 @@ void LLVOAvatarSelf::resetJointPositions( void )  	return LLVOAvatar::resetJointPositions();  }  // virtual -BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake ) +BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake )  {  	if (!which_param)  	{ @@ -723,7 +727,7 @@ BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight, BOOL upload_bak  	return setParamWeight(param,weight,upload_bake);  } -BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake ) +BOOL LLVOAvatarSelf::setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake )  {  	if (!param)  	{ @@ -736,7 +740,7 @@ BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL  		U32 size = gAgentWearables.getWearableCount(type);  		for (U32 count = 0; count < size; ++count)  		{ -			LLViewerWearable *wearable = gAgentWearables.getWearable(type,count); +			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(type,count);  			if (wearable)  			{  				wearable->setVisualParamWeight(param->getID(), weight, upload_bake); @@ -762,7 +766,7 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()  	// apply wearable visual params to avatar  	for (U32 type = 0; type < LLWearableType::WT_COUNT; type++)  	{ -		LLViewerWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type); +		LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);  		if (wearable)  		{  			wearable->writeToAvatar(); @@ -1257,7 +1261,7 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)  		// Make sure the inventory is in sync with the avatar.  		// Update COF contents, don't trigger appearance update. -		if (!isAgentAvatarValid()) +		if (!isValid())  		{  			llinfos << "removeItemLinks skipped, avatar is under destruction" << llendl;  		} @@ -1780,7 +1784,7 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te  			return;  		}  		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(type); -		if (!gAgentWearables.getWearable(wearable_type,index)) +		if (!gAgentWearables.getViewerWearable(wearable_type,index))  		{  			// no wearable is loaded, cannot set the texture.  			return; @@ -1796,7 +1800,7 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te  		LLViewerTexLayerSet *layer_set = getLayerSet(type);  		if (layer_set)  		{ -			layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getWearable(wearable_type,index)); +			layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getViewerWearable(wearable_type,index));  		}  	} @@ -2286,7 +2290,7 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const  		for (U32 wearable_index = 0; wearable_index < count; ++wearable_index)  		{ -			LLViewerWearable *wearable = gAgentWearables.getWearable(wearable_type, wearable_index); +			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, wearable_index);  			if (wearable)  			{  				const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index); @@ -2361,7 +2365,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 wearable_index) const  {  	LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i); -	LLViewerWearable* wearable = gAgentWearables.getWearable(type, wearable_index); +	LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index);  	if (wearable)  	{  		return wearable->getLocalTextureObject(i); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 12886d2d36..2fe960cd1e 100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -97,7 +97,7 @@ public:  				void		resetJointPositions( void ); -	/*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE ); +	/*virtual*/ BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );  	/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );  	/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );  	/*virtual*/ void updateVisualParams(); @@ -111,7 +111,7 @@ public:  private:  	// helper function. Passed in param is assumed to be in avatar's parameter list. -	BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE ); +	BOOL setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE ); @@ -131,6 +131,7 @@ private:  public:  	/*virtual*/ bool 	isSelf() const { return true; } +	/*virtual*/ BOOL	isValid() const;  	//--------------------------------------------------------------------  	// Updates | 
