diff options
| -rw-r--r-- | indra/llappearance/llavatarappearance.cpp | 45 | ||||
| -rw-r--r-- | indra/llappearance/llavatarappearance.h | 4 | ||||
| -rw-r--r-- | indra/llappearance/lltexlayer.cpp | 2 | ||||
| -rw-r--r-- | indra/llappearance/llwearable.cpp | 138 | ||||
| -rw-r--r-- | indra/llappearance/llwearable.h | 18 | ||||
| -rwxr-xr-x | indra/newview/llagentwearables.cpp | 6 | ||||
| -rwxr-xr-x | indra/newview/llappearancemgr.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/llpolymorph.cpp | 747 | ||||
| -rw-r--r-- | indra/newview/llpolymorph.h | 182 | ||||
| -rw-r--r-- | indra/newview/llscrollingpanelparam.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llscrollingpanelparambase.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerwearable.cpp | 116 | ||||
| -rw-r--r-- | indra/newview/llviewerwearable.h | 14 | ||||
| -rwxr-xr-x | indra/newview/llvoavatar.cpp | 47 | ||||
| -rwxr-xr-x | indra/newview/llvoavatar.h | 1 | ||||
| -rwxr-xr-x | indra/newview/llvoavatarself.cpp | 33 | ||||
| -rwxr-xr-x | indra/newview/llvoavatarself.h | 6 | ||||
| -rw-r--r-- | indra/newview/llwearablelist.cpp | 20 | ||||
| -rw-r--r-- | indra/newview/llwearablelist.h | 3 | 
19 files changed, 253 insertions, 1140 deletions
| diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index e2dfa2fb74..7d37f5f509 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -1332,43 +1332,16 @@ LLColor4 LLAvatarAppearance::getGlobalColor( const std::string& color_name ) con  // 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 -	} +	return mWearableData->getWearableCount(type) > 0; +} -	/* 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; +LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_index) const +{ +	/* switch(index) +		case TEX_HEAD_BAKED: +		case TEX_HEAD_BODYPAINT: +			return mHeadLayerSet; */ +	return mBakedTextureDatas[baked_index].mTexLayerSet;  }  //----------------------------------------------------------------------------- diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 6eab9b9d1f..b512fd4eda 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -269,8 +269,12 @@ private:   **                                                                            **   **                    BAKED TEXTURES   **/ +public: +	LLTexLayerSet*		getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const; +  protected:  	virtual LLTexLayerSet*	createTexLayerSet() = 0; +  protected:  	class LLMaskedMorph;  	typedef std::deque<LLMaskedMorph *> 	morph_list_t; diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 1325267dc2..e90efac36b 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1620,7 +1620,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const  		}  		if (layer)  		{ -			wearable->writeToAvatar(); +			wearable->writeToAvatar(mAvatarAppearance);  			layer->setLTO(lto);  			success &= layer->render(x,y,width,height);  		} diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index ea14c6320f..9e73a6669a 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -123,27 +123,80 @@ BOOL LLWearable::exportFile(LLFILE* file) const  	}  	// texture entries -	S32 num_textures = mTextureIDMap.size(); +	S32 num_textures = mTEMap.size();  	if( fprintf( file, "textures %d\n", num_textures ) < 0 )  	{ -		return FALSE; +			return FALSE;  	} -	 -	for (texture_id_map_t::const_iterator iter = mTextureIDMap.begin(); iter != mTextureIDMap.end(); ++iter) + +	for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)  	{ -		S32 te = iter->first; -		const LLUUID& image_id = iter->second; -		if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 ) +			S32 te = iter->first; +			const LLUUID& image_id = iter->second->getID(); +			if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 ) +			{ +					return FALSE; +			} +	} +	return TRUE; +} + +void LLWearable::createVisualParams(LLAvatarAppearance *avatarp) +{ +	for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatarp->getFirstVisualParam();  +		 param; +		 param = (LLViewerVisualParam*) avatarp->getNextVisualParam()) +	{ +		if (param->getWearableType() == mType)  		{ -			return FALSE; +			addVisualParam(param->cloneParam(this)); +		} +	} + +	// resync driver parameters to point to the newly cloned driven parameters +	for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin();  +		 param_iter != mVisualParamIndexMap.end();  +		 ++param_iter) +	{ +		LLVisualParam* param = param_iter->second; +		LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam;  +		// need this line to disambiguate between versions of LLCharacter::getVisualParam() +		LLVisualParam*(LLAvatarAppearance::*param_function)(S32)const = &LLAvatarAppearance::getVisualParam;  +		param->resetDrivenParams(); +		if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false)) +		{ +			if( !param->linkDrivenParams(boost::bind(param_function,avatarp,_1 ), true)) +			{ +				llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl; +				continue; +			}  		}  	} -	return TRUE;  } +void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp) +{ +	LLTexLayerSet *layer_set = NULL; +	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te); +	if (texture_dict->mIsUsedByBakedTexture) +	{ +		const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; +		 +		 layer_set = avatarp->getAvatarLayerSet(baked_index); +	} + +	if (layer_set) +	{ +		   layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this); +	} +	else +	{ +		   llerrs << "could not find layerset for LTO in wearable!" << llendl; +	} +}  // virtual -LLWearable::EImportResult LLWearable::importFile( LLFILE* file ) +LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearance* avatarp )  {  	// *NOTE: changing the type or size of this buffer will require  	// changes in the fscanf() code below. You would be better off @@ -158,6 +211,11 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file )  		return LLWearable::BAD_HEADER;  	} +	if(!avatarp) +	{ +		return LLWearable::FAILURE; +	} +  	// Temporary hack to allow wearables with definition version 24 to still load.  	// This should only affect lindens and NDA'd testers who have saved wearables in 2.0 @@ -265,7 +323,7 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file )  	}  	if( 0 <= type && type < LLWearableType::WT_COUNT )  	{ -		setType((LLWearableType::EType)type); +		setType((LLWearableType::EType)type, avatarp);  	}  	else  	{ @@ -313,37 +371,49 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file )  	}  	// textures -	mTextureIDMap.clear();  	for( i = 0; i < num_textures; i++ )  	{  		S32 te = 0; -		fields_read = fscanf(	/* Flawfinder: ignore */ -			file, -			"%d %2047s\n", -			&te, text_buffer); +		fields_read = fscanf(   /* Flawfinder: ignore */ +				file, +				"%d %2047s\n", +				&te, text_buffer);  		if( fields_read != 2 )  		{ -			llwarns << "Bad Wearable asset: bad texture, #" << i << llendl; -			return LLWearable::FAILURE; +				llwarns << "Bad Wearable asset: bad texture, #" << i << llendl; +				return LLWearable::FAILURE;  		} - +	  		if( !LLUUID::validate( text_buffer ) )  		{ -			llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl; -			return LLWearable::FAILURE; +				llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl; +				return LLWearable::FAILURE;  		}  		LLUUID id = LLUUID(text_buffer); -		mTextureIDMap[te] = id; +		LLGLTexture* image = gTextureManagerBridgep->getFetchedTexture( id ); +		if( mTEMap.find(te) != mTEMap.end() ) +		{ +				delete mTEMap[te]; +		} +		if( mSavedTEMap.find(te) != mSavedTEMap.end() ) +		{ +				delete mSavedTEMap[te]; +		} +	 +		LLUUID textureid(text_buffer); +		mTEMap[te] = new LLLocalTextureObject(image, textureid); +		mSavedTEMap[te] = new LLLocalTextureObject(image, textureid); +		createLayers(te, avatarp);  	}  	return LLWearable::SUCCESS;  } -void LLWearable::setType(LLWearableType::EType type)  +void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp)   {   	mType = type;  -	createVisualParams(); +	createVisualParams(avatarp);  } @@ -442,6 +512,26 @@ void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload  	}  } +void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp) +{ +	if (!avatarp) return; + +	// Pull params +	for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() ) +	{ +		// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the +		// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way. +		if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) ) +		{ +			S32 param_id = param->getID(); +			F32 weight = getVisualParamWeight(param_id); + +			avatarp->setVisualParamWeight( param_id, weight, FALSE ); +		} +	} +} + +  std::string terse_F32_to_string(F32 f)  {  	std::string r = llformat("%.2f", f); diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index e1cd26bdef..b8bbf82a6e 100644 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -37,6 +37,7 @@ class LLMD5;  class LLVisualParam;  class LLTexGlobalColorInfo;  class LLTexGlobalColor; +class LLAvatarAppearance;  // Abstract class.  class LLWearable @@ -52,7 +53,7 @@ public:  	//--------------------------------------------------------------------  public:  	LLWearableType::EType		getType() const	{ return mType; } -	void						setType(LLWearableType::EType type); +	void						setType(LLWearableType::EType type, LLAvatarAppearance *avatarp);  	const std::string&			getName() const	{ return mName; }  	void						setName(const std::string& name) { mName = name; }  	const std::string&			getDescription() const { return mDescription; } @@ -70,7 +71,7 @@ public:  public:  	typedef std::vector<LLVisualParam*> visual_param_vec_t; -	virtual void	writeToAvatar() = 0; +	virtual void	writeToAvatar(LLAvatarAppearance* avatarp);  	enum EImportResult  	{ @@ -79,7 +80,7 @@ public:  		BAD_HEADER  	};  	virtual BOOL				exportFile(LLFILE* file) const; -	virtual EImportResult		importFile(LLFILE* file); +	virtual EImportResult		importFile(LLFILE* file, LLAvatarAppearance* avatarp); @@ -96,9 +97,6 @@ public:  	LLColor4			getClothesColor(S32 te) const;  	void 				setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake ); -	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; @@ -106,7 +104,8 @@ public:  	virtual void		addToBakedTextureHash(LLMD5& hash) const = 0;  protected: -	virtual void 	createVisualParams() = 0; +	void			 	createVisualParams(LLAvatarAppearance *avatarp); +	void 				createLayers(S32 te, LLAvatarAppearance *avatarp);  	static S32			sCurrentDefinitionVersion;	// Depends on the current state of the avatar_lad.xml.  	S32					mDefinitionVersion;			// Depends on the state of the avatar_lad.xml when this asset was created. @@ -122,8 +121,9 @@ protected:  	typedef std::map<S32, LLVisualParam *>    visual_param_index_map_t;  	visual_param_index_map_t mVisualParamIndexMap; -	// *TODO: Lazy mutable.  Find a better way? -	mutable texture_id_map_t mTextureIDMap; +	typedef std::map<S32, LLLocalTextureObject*> te_map_t; +	te_map_t mTEMap;				// maps TE to LocalTextureObject +	te_map_t mSavedTEMap;			// last saved version of TEMap  };  #endif  // LL_LLWEARABLE_H diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 40cedc1b35..e2304e6db9 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -898,7 +898,7 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,  	// Try to recover by replacing missing wearable with a new one.  	LLNotificationsUtil::add("ReplacedMissingWearable");  	lldebugs << "Wearable " << LLWearableType::getTypeLabel(type) << " could not be downloaded.  Replaced inventory item with default wearable." << llendl; -	LLViewerWearable* new_wearable = LLWearableList::instance().createNewWearable(type); +	LLViewerWearable* new_wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);  	setWearable(type,index,new_wearable);  	//new_wearable->writeToAvatar(TRUE); @@ -1048,7 +1048,7 @@ void LLAgentWearables::createStandardWearables()  		if (create[i])  		{  			llassert(getWearableCount((LLWearableType::EType)i) == 0); -			LLViewerWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i); +			LLViewerWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i, gAgentAvatarp);  			((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);  			// no need to update here...  			LLUUID category_id = LLUUID::null; @@ -1786,7 +1786,7 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con  {  	if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; -	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type); +	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);  	LLAssetType::EType asset_type = wearable->getAssetType();  	LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;  	LLPointer<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 5717ebaf02..1e4e00d77d 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -665,7 +665,7 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type  	LLNotificationsUtil::add("ReplacedMissingWearable");  	lldebugs << "Wearable " << LLWearableType::getTypeLabel(type)  			 << " could not be downloaded.  Replaced inventory item with default wearable." << llendl; -	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type); +	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);  	// Add a new one in the lost and found folder.  	const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); @@ -1841,6 +1841,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)  		// Fetch the wearables about to be worn.  		LLWearableList::instance().getAsset(found.mAssetID,  											found.mName, +											gAgentAvatarp,  											found.mAssetType,  											onWearableAssetFetch,  											(void*)holder); diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp deleted file mode 100644 index d25d1420ee..0000000000 --- a/indra/newview/llpolymorph.cpp +++ /dev/null @@ -1,747 +0,0 @@ -/**  - * @file llpolymorph.cpp - * @brief Implementation of LLPolyMesh class - * - * $LicenseInfo:firstyear=2001&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$ - */ - -//----------------------------------------------------------------------------- -// Header Files -//----------------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h" - -#include "llpolymorph.h" -#include "llvoavatar.h" -#include "llwearable.h" -#include "llxmltree.h" -#include "llendianswizzle.h" - -//#include "../tools/imdebug/imdebug.h" - -const F32 NORMAL_SOFTEN_FACTOR = 0.65f; - -//----------------------------------------------------------------------------- -// LLPolyMorphData() -//----------------------------------------------------------------------------- -LLPolyMorphData::LLPolyMorphData(const std::string& morph_name) -	: mName(morph_name) -{ -	mNumIndices = 0; -	mCurrentIndex = 0; -	mTotalDistortion = 0.f; -	mAvgDistortion.clear(); -	mMaxDistortion = 0.f; -	mVertexIndices = NULL; -	mCoords = NULL; -	mNormals = NULL; -	mBinormals = NULL; -	mTexCoords = NULL; - -	mMesh = NULL; -} - -LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : -	mName(rhs.mName), -	mNumIndices(rhs.mNumIndices), -	mTotalDistortion(rhs.mTotalDistortion), -	mAvgDistortion(rhs.mAvgDistortion), -	mMaxDistortion(rhs.mMaxDistortion), -	mVertexIndices(NULL), -	mCoords(NULL), -	mNormals(NULL), -	mBinormals(NULL), -	mTexCoords(NULL) -{ -	const S32 numVertices = mNumIndices; - -	mCoords = new LLVector4a[numVertices]; -	mNormals = new LLVector4a[numVertices]; -	mBinormals = new LLVector4a[numVertices]; -	mTexCoords = new LLVector2[numVertices]; -	mVertexIndices = new U32[numVertices]; -	 -	for (S32 v=0; v < numVertices; v++) -	{ -		mCoords[v] = rhs.mCoords[v]; -		mNormals[v] = rhs.mNormals[v]; -		mBinormals[v] = rhs.mBinormals[v]; -		mTexCoords[v] = rhs.mTexCoords[v]; -		mVertexIndices[v] = rhs.mVertexIndices[v]; -	} -} - - -//----------------------------------------------------------------------------- -// ~LLPolyMorphData() -//----------------------------------------------------------------------------- -LLPolyMorphData::~LLPolyMorphData() -{ -	delete [] mVertexIndices; -	delete [] mCoords; -	delete [] mNormals; -	delete [] mBinormals; -	delete [] mTexCoords; -} - -//----------------------------------------------------------------------------- -// loadBinary() -//----------------------------------------------------------------------------- -BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) -{ -	S32 numVertices; -	S32 numRead; - -	numRead = fread(&numVertices, sizeof(S32), 1, fp); -	llendianswizzle(&numVertices, sizeof(S32), 1); -	if (numRead != 1) -	{ -		llwarns << "Can't read number of morph target vertices" << llendl; -		return FALSE; -	} - -	//------------------------------------------------------------------------- -	// allocate vertices -	//------------------------------------------------------------------------- -	mCoords = new LLVector4a[numVertices]; -	mNormals = new LLVector4a[numVertices]; -	mBinormals = new LLVector4a[numVertices]; -	mTexCoords = new LLVector2[numVertices]; -	// Actually, we are allocating more space than we need for the skiplist -	mVertexIndices = new U32[numVertices]; -	mNumIndices = 0; -	mTotalDistortion = 0.f; -	mMaxDistortion = 0.f; -	mAvgDistortion.clear(); -	mMesh = mesh; - -	//------------------------------------------------------------------------- -	// read vertices -	//------------------------------------------------------------------------- -	for(S32 v = 0; v < numVertices; v++) -	{ -		numRead = fread(&mVertexIndices[v], sizeof(U32), 1, fp); -		llendianswizzle(&mVertexIndices[v], sizeof(U32), 1); -		if (numRead != 1) -		{ -			llwarns << "Can't read morph target vertex number" << llendl; -			return FALSE; -		} - -		if (mVertexIndices[v] > 10000) -		{ -			llerrs << "Bad morph index: " << mVertexIndices[v] << llendl; -		} - - -		numRead = fread(&mCoords[v], sizeof(F32), 3, fp); -		llendianswizzle(&mCoords[v], sizeof(F32), 3); -		if (numRead != 3) -		{ -			llwarns << "Can't read morph target vertex coordinates" << llendl; -			return FALSE; -		} - -		F32 magnitude = mCoords[v].getLength3().getF32(); -		 -		mTotalDistortion += magnitude; -		LLVector4a t; -		t.setAbs(mCoords[v]); -		mAvgDistortion.add(t); -		 -		if (magnitude > mMaxDistortion) -		{ -			mMaxDistortion = magnitude; -		} - -		numRead = fread(&mNormals[v], sizeof(F32), 3, fp); -		llendianswizzle(&mNormals[v], sizeof(F32), 3); -		if (numRead != 3) -		{ -			llwarns << "Can't read morph target normal" << llendl; -			return FALSE; -		} - -		numRead = fread(&mBinormals[v], sizeof(F32), 3, fp); -		llendianswizzle(&mBinormals[v], sizeof(F32), 3); -		if (numRead != 3) -		{ -			llwarns << "Can't read morph target binormal" << llendl; -			return FALSE; -		} - - -		numRead = fread(&mTexCoords[v].mV, sizeof(F32), 2, fp); -		llendianswizzle(&mTexCoords[v].mV, sizeof(F32), 2); -		if (numRead != 2) -		{ -			llwarns << "Can't read morph target uv" << llendl; -			return FALSE; -		} - -		mNumIndices++; -	} - -	mAvgDistortion.mul(1.f/(F32)mNumIndices); -	mAvgDistortion.normalize3fast(); - -	return TRUE; -} - -//----------------------------------------------------------------------------- -// LLPolyMorphTargetInfo() -//----------------------------------------------------------------------------- -LLPolyMorphTargetInfo::LLPolyMorphTargetInfo() -	: mIsClothingMorph(FALSE) -{ -} - -BOOL LLPolyMorphTargetInfo::parseXml(LLXmlTreeNode* node) -{ -	llassert( node->hasName( "param" ) && node->getChildByName( "param_morph" ) ); - -	if (!LLViewerVisualParamInfo::parseXml(node)) -		return FALSE; - -	// Get mixed-case name -	static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); -	if( !node->getFastAttributeString( name_string, mMorphName ) ) -	{ -		llwarns << "Avatar file: <param> is missing name attribute" << llendl; -		return FALSE;  // Continue, ignoring this tag -	} - -	static LLStdStringHandle clothing_morph_string = LLXmlTree::addAttributeString("clothing_morph"); -	node->getFastAttributeBOOL(clothing_morph_string, mIsClothingMorph); - -	LLXmlTreeNode *paramNode = node->getChildByName("param_morph"); - -        if (NULL == paramNode) -        { -                llwarns << "Failed to getChildByName(\"param_morph\")" -                        << llendl; -                return FALSE; -        } - -	for (LLXmlTreeNode* child_node = paramNode->getFirstChild(); -		 child_node; -		 child_node = paramNode->getNextChild()) -	{ -		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); -		if (child_node->hasName("volume_morph")) -		{ -			std::string volume_name; -			if (child_node->getFastAttributeString(name_string, volume_name)) -			{ -				LLVector3 scale; -				static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); -				child_node->getFastAttributeVector3(scale_string, scale); -				 -				LLVector3 pos; -				static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); -				child_node->getFastAttributeVector3(pos_string, pos); - -				mVolumeInfoList.push_back(LLPolyVolumeMorphInfo(volume_name,scale,pos)); -			} -		} -	} -	 -	return TRUE; -} - -//----------------------------------------------------------------------------- -// LLPolyMorphTarget() -//----------------------------------------------------------------------------- -LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh) -	: mMorphData(NULL), mMesh(poly_mesh), -	  mVertMask(NULL), -	  mLastSex(SEX_FEMALE), -	  mNumMorphMasksPending(0) -{ -} - -//----------------------------------------------------------------------------- -// ~LLPolyMorphTarget() -//----------------------------------------------------------------------------- -LLPolyMorphTarget::~LLPolyMorphTarget() -{ -	if (mVertMask) -	{ -		delete mVertMask; -	} -} - -//----------------------------------------------------------------------------- -// setInfo() -//----------------------------------------------------------------------------- -BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info) -{ -	llassert(mInfo == NULL); -	if (info->mID < 0) -		return FALSE; -	mInfo = info; -	mID = info->mID; -	setWeight(getDefaultWeight(), FALSE ); - -	LLVOAvatar* avatarp = mMesh->getAvatar(); -	LLPolyMorphTargetInfo::volume_info_list_t::iterator iter; -	for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++) -	{ -		LLPolyVolumeMorphInfo *volume_info = &(*iter); -		for (S32 i = 0; i < avatarp->mNumCollisionVolumes; i++) -		{ -			if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName) -			{ -				mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i], -														  volume_info->mScale, -														  volume_info->mPos)); -				break; -			} -		} -	} - -	std::string morph_param_name = getInfo()->mMorphName; -	 -	mMorphData = mMesh->getMorphData(morph_param_name); -	if (!mMorphData) -	{ -		const std::string driven_tag = "_Driven"; -		U32 pos = morph_param_name.find(driven_tag); -		if (pos > 0) -		{ -			morph_param_name = morph_param_name.substr(0,pos); -			mMorphData = mMesh->getMorphData(morph_param_name); -		} -	} -	if (!mMorphData) -	{ -		llwarns << "No morph target named " << morph_param_name << " found in mesh." << llendl; -		return FALSE;  // Continue, ignoring this tag -	} -	return TRUE; -} - -/*virtual*/ LLViewerVisualParam* LLPolyMorphTarget::cloneParam(LLWearable* wearable) const -{ -	LLPolyMorphTarget *new_param = new LLPolyMorphTarget(mMesh); -	*new_param = *this; -	return new_param; -} - -#if 0 // obsolete -//----------------------------------------------------------------------------- -// parseData() -//----------------------------------------------------------------------------- -BOOL LLPolyMorphTarget::parseData(LLXmlTreeNode* node) -{ -	LLPolyMorphTargetInfo* info = new LLPolyMorphTargetInfo; - -	info->parseXml(node); -	if (!setInfo(info)) -	{ -		delete info; -		return FALSE; -	} -	return TRUE; -} -#endif - -//----------------------------------------------------------------------------- -// getVertexDistortion() -//----------------------------------------------------------------------------- -LLVector4a LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh) -{ -	if (!mMorphData || mMesh != mesh) return LLVector4a::getZero(); - -	for(U32 index = 0; index < mMorphData->mNumIndices; index++) -	{ -		if (mMorphData->mVertexIndices[index] == (U32)requested_index) -		{ -			return mMorphData->mCoords[index]; -		} -	} - -	return LLVector4a::getZero(); -} - -//----------------------------------------------------------------------------- -// getFirstDistortion() -//----------------------------------------------------------------------------- -const LLVector4a *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) -{ -	if (!mMorphData) return &LLVector4a::getZero(); - -	LLVector4a* resultVec; -	mMorphData->mCurrentIndex = 0; -	if (mMorphData->mNumIndices) -	{ -		resultVec = &mMorphData->mCoords[mMorphData->mCurrentIndex]; -		if (index != NULL) -		{ -			*index = mMorphData->mVertexIndices[mMorphData->mCurrentIndex]; -		} -		if (poly_mesh != NULL) -		{ -			*poly_mesh = mMesh; -		} - -		return resultVec; -	} -	return NULL; -} - -//----------------------------------------------------------------------------- -// getNextDistortion() -//----------------------------------------------------------------------------- -const LLVector4a *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) -{ -	if (!mMorphData) return &LLVector4a::getZero(); - -	LLVector4a* resultVec; -	mMorphData->mCurrentIndex++; -	if (mMorphData->mCurrentIndex < mMorphData->mNumIndices) -	{ -		resultVec = &mMorphData->mCoords[mMorphData->mCurrentIndex]; -		if (index != NULL) -		{ -			*index = mMorphData->mVertexIndices[mMorphData->mCurrentIndex]; -		} -		if (poly_mesh != NULL) -		{ -			*poly_mesh = mMesh; -		} -		return resultVec; -	} -	return NULL; -} - -//----------------------------------------------------------------------------- -// getTotalDistortion() -//----------------------------------------------------------------------------- -F32	LLPolyMorphTarget::getTotalDistortion()  -{  -	if (mMorphData)  -	{ -		return mMorphData->mTotalDistortion;  -	} -	else  -	{ -		return 0.f; -	} -} - -//----------------------------------------------------------------------------- -// getAvgDistortion() -//----------------------------------------------------------------------------- -const LLVector4a& LLPolyMorphTarget::getAvgDistortion()	 -{ -	if (mMorphData)  -	{ -		return mMorphData->mAvgDistortion;  -	} -	else  -	{ -		return LLVector4a::getZero(); -	} -} - -//----------------------------------------------------------------------------- -// getMaxDistortion() -//----------------------------------------------------------------------------- -F32	LLPolyMorphTarget::getMaxDistortion()  -{ -	if (mMorphData)  -	{ -		return mMorphData->mMaxDistortion;  -	} -	else -	{ -		return 0.f; -	} -} - -//----------------------------------------------------------------------------- -// apply() -//----------------------------------------------------------------------------- -static LLFastTimer::DeclareTimer FTM_APPLY_MORPH_TARGET("Apply Morph"); - -void LLPolyMorphTarget::apply( ESex avatar_sex ) -{ -	if (!mMorphData || mNumMorphMasksPending > 0) -	{ -		return; -	} - -	LLFastTimer t(FTM_APPLY_MORPH_TARGET); - -	mLastSex = avatar_sex; - -	// Check for NaN condition (NaN is detected if a variable doesn't equal itself. -	if (mCurWeight != mCurWeight) -	{ -		mCurWeight = 0.0; -	} -	if (mLastWeight != mLastWeight) -	{ -		mLastWeight = mCurWeight+.001; -	} - -	// perform differential update of morph -	F32 delta_weight = ( getSex() & avatar_sex ) ? (mCurWeight - mLastWeight) : (getDefaultWeight() - mLastWeight); -	// store last weight -	mLastWeight += delta_weight; - -	if (delta_weight != 0.f) -	{ -		llassert(!mMesh->isLOD()); -		LLVector4a *coords = mMesh->getWritableCoords(); - -		LLVector4a *scaled_normals = mMesh->getScaledNormals(); -		LLVector4a *normals = mMesh->getWritableNormals(); - -		LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); -		LLVector4a *binormals = mMesh->getWritableBinormals(); - -		LLVector4a *clothing_weights = mMesh->getWritableClothingWeights(); -		LLVector2 *tex_coords = mMesh->getWritableTexCoords(); - -		F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL; - -		for(U32 vert_index_morph = 0; vert_index_morph < mMorphData->mNumIndices; vert_index_morph++) -		{ -			S32 vert_index_mesh = mMorphData->mVertexIndices[vert_index_morph]; - -			F32 maskWeight = 1.f; -			if (maskWeightArray) -			{ -				maskWeight = maskWeightArray[vert_index_morph]; -			} - - -			LLVector4a pos = mMorphData->mCoords[vert_index_morph]; -			pos.mul(delta_weight*maskWeight); -			coords[vert_index_mesh].add(pos); - -			if (getInfo()->mIsClothingMorph && clothing_weights) -			{ -				LLVector4a clothing_offset = mMorphData->mCoords[vert_index_morph]; -				clothing_offset.mul(delta_weight * maskWeight); -				LLVector4a* clothing_weight = &clothing_weights[vert_index_mesh]; -				clothing_weight->add(clothing_offset); -				clothing_weight->getF32ptr()[VW] = maskWeight; -			} - -			// calculate new normals based on half angles -			LLVector4a norm = mMorphData->mNormals[vert_index_morph]; -			norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); -			scaled_normals[vert_index_mesh].add(norm); -			norm = scaled_normals[vert_index_mesh]; -			norm.normalize3fast(); -			normals[vert_index_mesh] = norm; - -			// calculate new binormals -			LLVector4a binorm = mMorphData->mBinormals[vert_index_morph]; -			binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); -			scaled_binormals[vert_index_mesh].add(binorm); -			LLVector4a tangent; -			tangent.setCross3(scaled_binormals[vert_index_mesh], norm); -			LLVector4a& normalized_binormal = binormals[vert_index_mesh]; -			normalized_binormal.setCross3(norm, tangent);  -			normalized_binormal.normalize3fast(); -			 -			tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight; -		} - -		// now apply volume changes -		for( volume_list_t::iterator iter = mVolumeMorphs.begin(); iter != mVolumeMorphs.end(); iter++ ) -		{ -			LLPolyVolumeMorph* volume_morph = &(*iter); -			LLVector3 scale_delta = volume_morph->mScale * delta_weight; -			LLVector3 pos_delta = volume_morph->mPos * delta_weight; -			 -			volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta); -			volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta); -		} -	} - -	if (mNext) -	{ -		mNext->apply(avatar_sex); -	} -} - -//----------------------------------------------------------------------------- -// applyMask() -//----------------------------------------------------------------------------- -void	LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert) -{ -	LLVector4a *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL; - -	if (!mVertMask) -	{ -		mVertMask = new LLPolyVertexMask(mMorphData); -		mNumMorphMasksPending--; -	} -	else -	{ -		// remove effect of previous mask -		F32 *maskWeights = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL; - -		if (maskWeights) -		{ -			LLVector4a *coords = mMesh->getWritableCoords(); -			LLVector4a *scaled_normals = mMesh->getScaledNormals(); -			LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); -			LLVector2 *tex_coords = mMesh->getWritableTexCoords(); - -			LLVector4Logical clothing_mask; -			clothing_mask.clear(); -			clothing_mask.setElement<0>(); -			clothing_mask.setElement<1>(); -			clothing_mask.setElement<2>(); - - -			for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++) -			{ -				F32 lastMaskWeight = mLastWeight * maskWeights[vert]; -				S32 out_vert = mMorphData->mVertexIndices[vert]; - -				// remove effect of existing masked morph -				LLVector4a t; -				t = mMorphData->mCoords[vert]; -				t.mul(lastMaskWeight); -				coords[out_vert].sub(t); - -				t = mMorphData->mNormals[vert]; -				t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); -				scaled_normals[out_vert].sub(t); - -				t = mMorphData->mBinormals[vert]; -				t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); -				scaled_binormals[out_vert].sub(t); - -				tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight; - -				if (clothing_weights) -				{ -					LLVector4a clothing_offset = mMorphData->mCoords[vert]; -					clothing_offset.mul(lastMaskWeight); -					LLVector4a* clothing_weight = &clothing_weights[out_vert]; -					LLVector4a t; -					t.setSub(*clothing_weight, clothing_offset); -					clothing_weight->setSelectWithMask(clothing_mask, t, *clothing_weight); -				} -			} -		} -	} - -	// set last weight to 0, since we've removed the effect of this morph -	mLastWeight = 0.f; - -	mVertMask->generateMask(maskTextureData, width, height, num_components, invert, clothing_weights); - -	apply(mLastSex); -} - - -//----------------------------------------------------------------------------- -// LLPolyVertexMask() -//----------------------------------------------------------------------------- -LLPolyVertexMask::LLPolyVertexMask(LLPolyMorphData* morph_data) -{ -	mWeights = new F32[morph_data->mNumIndices]; -	mMorphData = morph_data; -	mWeightsGenerated = FALSE; -} - -//----------------------------------------------------------------------------- -// ~LLPolyVertexMask() -//----------------------------------------------------------------------------- -LLPolyVertexMask::~LLPolyVertexMask() -{ -	delete[] mWeights; -} - -//----------------------------------------------------------------------------- -// generateMask() -//----------------------------------------------------------------------------- -void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights) -{ -// RN debug output that uses Image Debugger (http://www.cs.unc.edu/~baxter/projects/imdebug/) -//	BOOL debugImg = FALSE;  -//	if (debugImg) -//	{ -//		if (invert) -//		{ -//			imdebug("lum rbga=rgba b=8 w=%d h=%d *-1 %p", width, height, maskTextureData); -//		} -//		else -//		{ -//			imdebug("lum rbga=rgba b=8 w=%d h=%d %p", width, height, maskTextureData); -//		} -//	} -	for (U32 index = 0; index < mMorphData->mNumIndices; index++) -	{ -		S32 vertIndex = mMorphData->mVertexIndices[index]; -		const S32 *sharedVertIndex = mMorphData->mMesh->getSharedVert(vertIndex); -		LLVector2 uvCoords; - -		if (sharedVertIndex) -		{ -			uvCoords = mMorphData->mMesh->getUVs(*sharedVertIndex); -		} -		else -		{ -			uvCoords = mMorphData->mMesh->getUVs(vertIndex); -		} -		U32 s = llclamp((U32)(uvCoords.mV[VX] * (F32)(width - 1)), (U32)0, (U32)width - 1); -		U32 t = llclamp((U32)(uvCoords.mV[VY] * (F32)(height - 1)), (U32)0, (U32)height - 1); -		 -		mWeights[index] = ((F32) maskTextureData[((t * width + s) * num_components) + (num_components - 1)]) / 255.f; -		 -		if (invert)  -		{ -			mWeights[index] = 1.f - mWeights[index]; -		} - -		// now apply step function -		// mWeights[index] = mWeights[index] > 0.95f ? 1.f : 0.f; - -		if (clothing_weights) -		{ -			clothing_weights[vertIndex].getF32ptr()[VW] = mWeights[index]; -		} -	} -	mWeightsGenerated = TRUE; -} - -//----------------------------------------------------------------------------- -// getMaskForMorphIndex() -//----------------------------------------------------------------------------- -F32* LLPolyVertexMask::getMorphMaskWeights() -{ -	if (!mWeightsGenerated) -	{ -		return NULL; -	} -	 -	return mWeights; -} diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h deleted file mode 100644 index 28d7755d4d..0000000000 --- a/indra/newview/llpolymorph.h +++ /dev/null @@ -1,182 +0,0 @@ -/**  - * @file llpolymorph.h - * @brief Implementation of LLPolyMesh class - * - * $LicenseInfo:firstyear=2001&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$ - */ - -#ifndef LL_LLPOLYMORPH_H -#define LL_LLPOLYMORPH_H - -#include <string> -#include <vector> - -#include "llviewervisualparam.h" - -class LLPolyMeshSharedData; -class LLVOAvatar; -class LLVector2; -class LLAvatarJointCollisionVolume; -class LLWearable; - -//----------------------------------------------------------------------------- -// LLPolyMorphData() -//----------------------------------------------------------------------------- -class LLPolyMorphData -{ -public: -	LLPolyMorphData(const std::string& morph_name); -	~LLPolyMorphData(); -	LLPolyMorphData(const LLPolyMorphData &rhs); - -	BOOL			loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh); -	const std::string& getName() { return mName; } - -public: -	std::string			mName; - -	// morphology -	U32					mNumIndices; -	U32*				mVertexIndices; -	U32					mCurrentIndex; -	LLVector4a*			mCoords; -	LLVector4a*			mNormals; -	LLVector4a*			mBinormals; -	LLVector2*			mTexCoords; - -	F32					mTotalDistortion;	// vertex distortion summed over entire morph -	F32					mMaxDistortion;		// maximum single vertex distortion in a given morph -	LLVector4a			mAvgDistortion;		// average vertex distortion, to infer directionality of the morph -	LLPolyMeshSharedData*	mMesh; -}; - -//----------------------------------------------------------------------------- -// LLPolyVertexMask() -//----------------------------------------------------------------------------- -class LLPolyVertexMask -{ -public: -	LLPolyVertexMask(LLPolyMorphData* morph_data); -	~LLPolyVertexMask(); - -	void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights); -	F32* getMorphMaskWeights(); - - -protected: -	F32*		mWeights; -	LLPolyMorphData *mMorphData; -	BOOL			mWeightsGenerated; - -}; - -//----------------------------------------------------------------------------- -// LLPolyMorphTarget Data structs -//----------------------------------------------------------------------------- -struct LLPolyVolumeMorphInfo -{ -	LLPolyVolumeMorphInfo(std::string &name, LLVector3 &scale, LLVector3 &pos) -		: mName(name), mScale(scale), mPos(pos) {}; - -	std::string						mName; -	LLVector3						mScale; -	LLVector3						mPos; -}; - -struct LLPolyVolumeMorph -{ -	LLPolyVolumeMorph(LLAvatarJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos) -		: mVolume(volume), mScale(scale), mPos(pos) {}; - -	LLAvatarJointCollisionVolume*	mVolume; -	LLVector3						mScale; -	LLVector3						mPos; -}; - -//----------------------------------------------------------------------------- -// LLPolyMorphTargetInfo -// Shared information for LLPolyMorphTargets -//----------------------------------------------------------------------------- -class LLPolyMorphTargetInfo : public LLViewerVisualParamInfo -{ -	friend class LLPolyMorphTarget; -public: -	LLPolyMorphTargetInfo(); -	/*virtual*/ ~LLPolyMorphTargetInfo() {}; -	 -	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node); - -protected: -	std::string		mMorphName; -	BOOL			mIsClothingMorph; -	typedef std::vector<LLPolyVolumeMorphInfo> volume_info_list_t; -	volume_info_list_t mVolumeInfoList;	 -}; - -//----------------------------------------------------------------------------- -// LLPolyMorphTarget -// A set of vertex data associated with morph target. -// These morph targets must be topologically consistent with a given Polymesh -// (share face sets) -//----------------------------------------------------------------------------- -class LLPolyMorphTarget : public LLViewerVisualParam -{ -public: -	LLPolyMorphTarget(LLPolyMesh *poly_mesh); -	~LLPolyMorphTarget(); - -	// Special: These functions are overridden by child classes -	LLPolyMorphTargetInfo*	getInfo() const { return (LLPolyMorphTargetInfo*)mInfo; } -	//   This sets mInfo and calls initialization functions -	BOOL					setInfo(LLPolyMorphTargetInfo *info); - -	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const; - -	// LLVisualParam Virtual functions -	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node); -	/*virtual*/ void				apply( ESex sex ); -	 -	// LLViewerVisualParam Virtual functions -	/*virtual*/ F32					getTotalDistortion(); -	/*virtual*/ const LLVector4a&	getAvgDistortion(); -	/*virtual*/ F32					getMaxDistortion(); -	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); -	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); -	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); - -	void	applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert); -	void	addPendingMorphMask() { mNumMorphMasksPending++; } - -protected: -	LLPolyMorphData*				mMorphData; -	LLPolyMesh*						mMesh; -	LLPolyVertexMask *				mVertMask; -	ESex							mLastSex; -	// number of morph masks that haven't been generated, must be 0 before this morph is applied -	BOOL							mNumMorphMasksPending;	 - -	typedef std::vector<LLPolyVolumeMorph> volume_list_t; -	volume_list_t 					mVolumeMorphs; - -}; - -#endif // LL_LLPOLYMORPH_H diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp index 05b82ba967..a7e24b86b1 100644 --- a/indra/newview/llscrollingpanelparam.cpp +++ b/indra/newview/llscrollingpanelparam.cpp @@ -267,7 +267,7 @@ void LLScrollingPanelParam::onHintHeldDown( LLVisualParamHint* hint )  				&& new_percent < slider->getMaxValue())  			{  				mWearable->setVisualParamWeight( hint->getVisualParam()->getID(), new_weight, FALSE); -				mWearable->writeToAvatar(); +				mWearable->writeToAvatar(gAgentAvatarp);  				gAgentAvatarp->updateVisualParams();  				slider->setValue( weightToPercent( new_weight ) ); @@ -300,7 +300,7 @@ void LLScrollingPanelParam::onHintMinMouseUp( void* userdata )  				&& new_percent < slider->getMaxValue())  			{  				self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE); -				self->mWearable->writeToAvatar(); +				self->mWearable->writeToAvatar(gAgentAvatarp);  				slider->setValue( self->weightToPercent( new_weight ) );  			}  		} @@ -334,7 +334,7 @@ void LLScrollingPanelParam::onHintMaxMouseUp( void* userdata )  					&& new_percent < slider->getMaxValue())  				{  					self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE); -					self->mWearable->writeToAvatar(); +					self->mWearable->writeToAvatar(gAgentAvatarp);  					slider->setValue( self->weightToPercent( new_weight ) );  				}  			} diff --git a/indra/newview/llscrollingpanelparambase.cpp b/indra/newview/llscrollingpanelparambase.cpp index 62e3039d2f..8e083ddb6c 100644 --- a/indra/newview/llscrollingpanelparambase.cpp +++ b/indra/newview/llscrollingpanelparambase.cpp @@ -94,7 +94,7 @@ void LLScrollingPanelParamBase::onSliderMoved(LLUICtrl* ctrl, void* userdata)  	if (current_weight != new_weight )  	{  		self->mWearable->setVisualParamWeight( param->getID(), new_weight, FALSE ); -		self->mWearable->writeToAvatar(); +		self->mWearable->writeToAvatar(gAgentAvatarp);  		gAgentAvatarp->updateVisualParams();  	}  } diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index eb3a212eae..8fe3aff0b0 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -90,60 +90,13 @@ LLViewerWearable::~LLViewerWearable()  }  // virtual -BOOL LLViewerWearable::exportFile(LLFILE* file) const -{ -	mTextureIDMap.clear(); -	for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter) -	{ -		S32 te = iter->first; -		const LLUUID& image_id = iter->second->getID(); -		mTextureIDMap[te] = image_id; -	} -	return LLWearable::exportFile(file); -} - - -void LLViewerWearable::createVisualParams() -{ -	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();  -		 param; -		 param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam()) -	{ -		if (param->getWearableType() == mType) -		{ -			addVisualParam(param->cloneParam(this)); -		} -	} - -	// resync driver parameters to point to the newly cloned driven parameters -	for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin();  -		 param_iter != mVisualParamIndexMap.end();  -		 ++param_iter) -	{ -		LLVisualParam* param = param_iter->second; -		LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam;  -		// need this line to disambiguate between versions of LLCharacter::getVisualParam() -		LLVisualParam*(LLAvatarAppearance::*param_function)(S32)const = &LLAvatarAppearance::getVisualParam;  -		param->resetDrivenParams(); -		if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false)) -		{ -			if( !param->linkDrivenParams(boost::bind(param_function,gAgentAvatarp.get(),_1 ), true)) -			{ -				llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl; -				continue; -			} -		} -	} -} - -// virtual -LLWearable::EImportResult LLViewerWearable::importFile( LLFILE* file ) +LLWearable::EImportResult LLViewerWearable::importFile( LLFILE* file, LLAvatarAppearance* avatarp )  {  	// suppress texlayerset updates while wearables are being imported. Layersets will be updated  	// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.  	LLOverrideBakedTextureUpdate stop_bakes(false); -	LLWearable::EImportResult result = LLWearable::importFile(file); +	LLWearable::EImportResult result = LLWearable::importFile(file, avatarp);  	if (LLWearable::FAILURE == result) return result;  	if (LLWearable::BAD_HEADER == result)  	{ @@ -157,19 +110,16 @@ LLWearable::EImportResult LLViewerWearable::importFile( LLFILE* file )  	LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );  	LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN ); -	texture_id_map_t::const_iterator iter = mTextureIDMap.begin(); -	texture_id_map_t::const_iterator end = mTextureIDMap.end(); +	te_map_t::const_iterator iter = mTEMap.begin(); +	te_map_t::const_iterator end = mTEMap.end();  	for (; iter != end; ++iter)  	{  		S32 te = iter->first; -		const LLUUID& textureid = iter->second; -		if( mTEMap.find(te) != mTEMap.end() ) -		{ -			delete mTEMap[te]; -		} -		if( mSavedTEMap.find(te) != mSavedTEMap.end() ) +		LLLocalTextureObject* lto = iter->second; +		LLUUID textureid = LLUUID::null; +		if (lto)  		{ -			delete mSavedTEMap[te]; +			textureid = lto->getID();  		}  		LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( textureid ); @@ -177,9 +127,6 @@ LLWearable::EImportResult LLViewerWearable::importFile( LLFILE* file )  		{  			image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(textureid, (LLAvatarAppearanceDefines::ETextureIndex)te), NULL);  		} -		mTEMap[te] = new LLLocalTextureObject(image, textureid); -		mSavedTEMap[te] = new LLLocalTextureObject(image, textureid); -		createLayers(te);  	}  	// copy all saved param values to working params @@ -335,7 +282,7 @@ void LLViewerWearable::setTexturesToDefaults()  			if( mTEMap.find(te) == mTEMap.end() )  			{  				mTEMap[te] = new LLLocalTextureObject(image, id); -				createLayers(te); +				createLayers(te, gAgentAvatarp);  			}  			else  			{ @@ -366,25 +313,17 @@ const LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index)  // Updates the user's avatar's appearance -void LLViewerWearable::writeToAvatar() +//virtual +void LLViewerWearable::writeToAvatar(LLAvatarAppearance *avatarp)  { -	if (!isAgentAvatarValid()) return; +	LLVOAvatarSelf* viewer_avatar = dynamic_cast<LLVOAvatarSelf*>(avatarp); -	ESex old_sex = gAgentAvatarp->getSex(); +	if (!avatarp || !viewer_avatar) return; -	// Pull params -	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() ) -	{ -		// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the -		// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way. -		if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) ) -		{ -			S32 param_id = param->getID(); -			F32 weight = getVisualParamWeight(param_id); +	ESex old_sex = avatarp->getSex(); + +	LLWearable::writeToAvatar(avatarp); -			gAgentAvatarp->setVisualParamWeight( param_id, weight, FALSE ); -		} -	}  	// Pull texture entries  	for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) @@ -403,14 +342,14 @@ void LLViewerWearable::writeToAvatar()  			}  			LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );  			// MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this. -			gAgentAvatarp->setLocalTextureTE(te, image, 0); +			viewer_avatar->setLocalTextureTE(te, image, 0);  		}  	} -	ESex new_sex = gAgentAvatarp->getSex(); +	ESex new_sex = avatarp->getSex();  	if( old_sex != new_sex )  	{ -		gAgentAvatarp->updateSexDependentLayerSets( FALSE ); +		viewer_avatar->updateSexDependentLayerSets( FALSE );  	}	  //	if( upload_bake ) @@ -472,7 +411,7 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)  	mPermissions = src->mPermissions;  	mSaleInfo = src->mSaleInfo; -	setType(src->mType); +	setType(src->mType, gAgentAvatarp);  	mSavedVisualParamMap.clear();  	// Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed) @@ -513,7 +452,7 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)  				mTEMap[te] = new LLLocalTextureObject(image, image_id);  				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);  			} -			createLayers(te); +			createLayers(te, gAgentAvatarp);  		}  	} @@ -632,19 +571,6 @@ void LLViewerWearable::revertValues()  	}  } -void LLViewerWearable::createLayers(S32 te) -{ -	LLViewerTexLayerSet *layer_set = gAgentAvatarp->getLayerSet((ETextureIndex)te); -	if (layer_set) -	{ -		layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this); -	} -	else -	{ -		llerrs << "could not find layerset for LTO in wearable!" << llendl; -	} -} -  void LLViewerWearable::saveValues()  {  	//update saved settings so wearable is no longer dirty diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h index b3c1e3c3ba..d8412b1c65 100644 --- a/indra/newview/llviewerwearable.h +++ b/indra/newview/llviewerwearable.h @@ -30,6 +30,8 @@  #include "llwearable.h"  #include "llavatarappearancedefines.h" +class LLVOAvatar; +  class LLViewerWearable : public LLWearable  {  	friend class LLWearableList; @@ -58,12 +60,11 @@ public:  	BOOL				isDirty() const;  	BOOL				isOldVersion() const; -	/*virtual*/ void	writeToAvatar(); +	/*virtual*/ void	writeToAvatar(LLAvatarAppearance *avatarp);  	void				removeFromAvatar( BOOL upload_bake )	{ LLViewerWearable::removeFromAvatar( mType, upload_bake ); }  	static void			removeFromAvatar( LLWearableType::EType type, BOOL upload_bake );  -	/*virtual*/ BOOL	exportFile(LLFILE* file) const; -	/*virtual*/ EImportResult	importFile(LLFILE* file); +	/*virtual*/ EImportResult	importFile(LLFILE* file, LLAvatarAppearance* avatarp);  	void				setParamsToDefaults();  	void				setTexturesToDefaults(); @@ -98,18 +99,11 @@ public:  	/*virtual*/void		addToBakedTextureHash(LLMD5& hash) const;  protected: -	typedef std::map<S32, LLLocalTextureObject*> te_map_t; - -	void 				createLayers(S32 te); -	/*virtual*/void 	createVisualParams(); -  	void				syncImages(te_map_t &src, te_map_t &dst);  	void				destroyTextures();	  	LLAssetID			mAssetID;  	LLTransactionID		mTransactionID; -	te_map_t mTEMap;				// maps TE to LocalTextureObject -	te_map_t mSavedTEMap;			// last saved version of TEMap  	LLUUID				mItemID;  // ID of the inventory item in the agent's inventory	  }; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 081f1d62ca..7772ae25a1 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5560,6 +5560,53 @@ S32 LLVOAvatar::getAttachmentCount()  	return count;  } +BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const +{ +	if (mIsDummy) return TRUE; + +	if (isSelf()) +	{ +		return LLAvatarAppearance::isWearingWearableType(type); +	} + +	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; +} + +  // virtual  void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result ) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index cc94c2a3eb..9b59e5f0eb 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -677,6 +677,7 @@ public:  	virtual BOOL 		detachObject(LLViewerObject *viewer_object);  	void				cleanupAttachedMesh( LLViewerObject* pVO );  	static LLVOAvatar*  findAvatarFromAttachment(LLViewerObject* obj); +	/*virtual*/ BOOL	isWearingWearableType(LLWearableType::EType type ) const;  protected:  	LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);  	void 				lazyAttach(); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 96fd41739f..d0ccde09e8 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -703,7 +703,7 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()  		LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);  		if (wearable)  		{ -			wearable->writeToAvatar(); +			wearable->writeToAvatar(this);  		}  	} @@ -1001,11 +1001,6 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)  	}  } -/*virtual*/ BOOL LLVOAvatarSelf::isWearingWearableType(LLWearableType::EType type ) const -{ -	return gAgentWearables.getWearableCount(type) > 0; -} -  //-----------------------------------------------------------------------------  // updatedWearable( LLWearableType::EType type )  // forces an update to any baked textures relevant to type. @@ -2616,17 +2611,17 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )  LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const  { -	/* switch(index) -		case TEX_HEAD_BAKED: -		case TEX_HEAD_BODYPAINT: -			return mHeadLayerSet; */ -	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index); -	if (texture_dict->mIsUsedByBakedTexture) -	{ -		const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; -		return getLayerSet(baked_index); -	} -	return NULL; +       /* switch(index) +               case TEX_HEAD_BAKED: +               case TEX_HEAD_BODYPAINT: +                       return mHeadLayerSet; */ +       const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index); +       if (texture_dict->mIsUsedByBakedTexture) +       { +               const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; +               return getLayerSet(baked_index); +       } +       return NULL;  }  LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const @@ -2637,12 +2632,14 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index)                         return mHeadLayerSet; */         if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES)         { -                       return  getTexLayerSet(baked_index); +		   return  getTexLayerSet(baked_index);         }         return NULL;  } + +  // static  void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)  { diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 907564f8e1..395874ee62 100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -249,8 +249,9 @@ public:  	void 				requestLayerSetUploads();  	void				requestLayerSetUpload(LLAvatarAppearanceDefines::EBakedTextureIndex i);  	void				requestLayerSetUpdate(LLAvatarAppearanceDefines::ETextureIndex i); -	LLViewerTexLayerSet*	getLayerSet(LLAvatarAppearanceDefines::ETextureIndex index) const; -	LLViewerTexLayerSet*	getLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const; +	LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const; +	LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::ETextureIndex index) const; +  	//--------------------------------------------------------------------  	// Composites @@ -299,7 +300,6 @@ protected:   **/  public: -	/*virtual*/ BOOL	isWearingWearableType(LLWearableType::EType type) const;  	void				wearableUpdated(LLWearableType::EType type, BOOL upload_result);  protected:  	U32 getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const; diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 6c4790ad77..50beaaec3f 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -42,13 +42,15 @@ struct LLWearableArrivedData  {  	LLWearableArrivedData(LLAssetType::EType asset_type,  		const std::string& wearable_name, +		LLAvatarAppearance* avatarp,  		void(*asset_arrived_callback)(LLViewerWearable*, void* userdata),  						  void* userdata) :  		mAssetType( asset_type ),  		mCallback( asset_arrived_callback ),   		mUserdata( userdata ),  		mName( wearable_name ), -		mRetries(0) +		mRetries(0), +		mAvatarp(avatarp)  		{}  	LLAssetType::EType mAssetType; @@ -56,6 +58,7 @@ struct LLWearableArrivedData  	void*	mUserdata;  	std::string mName;  	S32	mRetries; +	LLAvatarAppearance *mAvatarp;  };  //////////////////////////////////////////////////////////////////////////// @@ -72,7 +75,7 @@ void LLWearableList::cleanup()  	mList.clear();  } -void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLViewerWearable*, void* userdata), void* userdata) +void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAvatarAppearance* avatarp, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLViewerWearable*, void* userdata), void* userdata)  {  	llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) );  	LLViewerWearable* instance = get_if_there(mList, assetID, (LLViewerWearable*)NULL ); @@ -85,7 +88,7 @@ void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& weara  		gAssetStorage->getAssetData(assetID,  			asset_type,  			LLWearableList::processGetAssetReply, -			(void*)new LLWearableArrivedData( asset_type, wearable_name, asset_arrived_callback, userdata ), +			(void*)new LLWearableArrivedData( asset_type, wearable_name, avatarp, asset_arrived_callback, userdata ),  			TRUE);  	}  } @@ -96,11 +99,16 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID  	BOOL isNewWearable = FALSE;  	LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;  	LLViewerWearable* wearable = NULL; // NULL indicates failure +	LLAvatarAppearance *avatarp = data->mAvatarp;  	if( !filename )  	{  		LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL;  	} +	else if(!avatarp) +	{ +		LL_WARNS("Wearable") << "Bad asset request: missing avatar pointer." << LL_ENDL; +	}  	else if (status >= 0)  	{  		// read the file @@ -112,7 +120,7 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID  		else  		{  			wearable = new LLViewerWearable(uuid); -			LLWearable::EImportResult result = wearable->importFile( fp ); +			LLWearable::EImportResult result = wearable->importFile( fp, avatarp );  			if (LLWearable::SUCCESS != result)  			{  				if (wearable->getType() == LLWearableType::WT_COUNT) @@ -222,12 +230,12 @@ LLViewerWearable* LLWearableList::createCopy(const LLViewerWearable* old_wearabl  	return wearable;  } -LLViewerWearable* LLWearableList::createNewWearable( LLWearableType::EType type ) +LLViewerWearable* LLWearableList::createNewWearable( LLWearableType::EType type, LLAvatarAppearance *avatarp )  {  	lldebugs << "LLWearableList::createNewWearable()" << llendl;  	LLViewerWearable *wearable = generateNewWearable(); -	wearable->setType( type ); +	wearable->setType( type, avatarp );  	std::string name = LLTrans::getString( LLWearableType::getTypeDefaultNewName(wearable->getType()) );  	wearable->setName( name ); diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h index 0f3078facf..d6f0fd09a6 100644 --- a/indra/newview/llwearablelist.h +++ b/indra/newview/llwearablelist.h @@ -50,12 +50,13 @@ public:  	void				getAsset(const LLAssetID& assetID,  								 const std::string& wearable_name, +								 LLAvatarAppearance *avatarp,  								 LLAssetType::EType asset_type,  								 void(*asset_arrived_callback)(LLViewerWearable*, void* userdata),  								 void* userdata);  	LLViewerWearable*			createCopy(const LLViewerWearable* old_wearable, const std::string& new_name = std::string()); -	LLViewerWearable*			createNewWearable(LLWearableType::EType type); +	LLViewerWearable*			createNewWearable(LLWearableType::EType type, LLAvatarAppearance *avatarp);  	// Callback  	static void	 	    processGetAssetReply(const char* filename, const LLAssetID& assetID, void* user_data, S32 status, LLExtStat ext_status); | 
