diff options
Diffstat (limited to 'indra/newview')
36 files changed, 2579 insertions, 3322 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9ec54f1851..76be212c95 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -203,7 +203,6 @@ set(viewer_SOURCE_FILES      llfollowcam.cpp      llframestats.cpp      llframestatview.cpp -    llgenepool.cpp      llgesturemgr.cpp      llgivemoney.cpp      llglsandbox.cpp @@ -406,6 +405,7 @@ set(viewer_SOURCE_FILES      llvlcomposition.cpp      llvlmanager.cpp      llvoavatar.cpp +    llvoavatardefines.cpp      llvocache.cpp      llvoclouds.cpp      llvograss.cpp @@ -605,7 +605,6 @@ set(viewer_HEADER_FILES      llfollowcam.h      llframestats.h      llframestatview.h -    llgenepool.h      llgesturemgr.h      llgivemoney.h      llgroupmgr.h @@ -810,6 +809,7 @@ set(viewer_HEADER_FILES      llvlcomposition.h      llvlmanager.h      llvoavatar.h +    llvoavatardefines.h      llvocache.h      llvoclouds.h      llvograss.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e964799e4c..993033aa2c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -561,17 +561,6 @@        <key>Value</key>        <integer>1</integer>      </map> -    <key>AvatarCompositeLimit</key> -    <map> -      <key>Comment</key> -      <string>Maximum number of avatars to display appearance changes on the fly</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>S32</string> -      <key>Value</key> -      <integer>5</integer> -    </map>      <key>AvatarFeathering</key>      <map>        <key>Comment</key> @@ -6152,6 +6141,17 @@        <key>Value</key>        <integer>35</integer>      </map> +    <key>RenderAvatarInvisible</key> +    <map> +      <key>Comment</key> +      <string>Set your avatar as Invisible</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>RenderAvatarVP</key>      <map>        <key>Comment</key> @@ -9922,6 +9922,17 @@        <key>Value</key>        <string>c80260ba-41fd-8a46-768a-6bf236360e3a</string>      </map> +	<key>UploadBakedTexOld</key> +    <map> +      <key>Comment</key> +      <string>Forces the baked texture pipeline to upload using the old method.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>UseAltKeyForMenus</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 569de267e7..d4978566da 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -133,6 +133,8 @@  #include "llviewerjoystick.h"  #include "llfollowcam.h" +using namespace LLVOAvatarDefines; +  extern LLMenuBarGL* gMenuBarView;  //drone wandering constants @@ -207,26 +209,6 @@ const F32 MIN_RADIUS_ALPHA_SIZZLE = 0.5f;  const F64 CHAT_AGE_FAST_RATE = 3.0; -const S32 MAX_WEARABLES_PER_LAYERSET = 7; - -const EWearableType WEARABLE_BAKE_TEXTURE_MAP[BAKED_TEXTURE_COUNT][MAX_WEARABLES_PER_LAYERSET] =  -{ -	{ WT_SHAPE,	WT_SKIN,	WT_HAIR,	WT_INVALID,	WT_INVALID,	WT_INVALID,		WT_INVALID    },	// TEX_HEAD_BAKED -	{ WT_SHAPE, WT_SKIN,	WT_SHIRT,	WT_JACKET,	WT_GLOVES,	WT_UNDERSHIRT,	WT_INVALID	  },	// TEX_UPPER_BAKED -	{ WT_SHAPE, WT_SKIN,	WT_PANTS,	WT_SHOES,	WT_SOCKS,	WT_JACKET,		WT_UNDERPANTS },	// TEX_LOWER_BAKED -	{ WT_EYES,	WT_INVALID,	WT_INVALID,	WT_INVALID,	WT_INVALID,	WT_INVALID,		WT_INVALID    },	// TEX_EYES_BAKED -	{ WT_SKIRT,	WT_INVALID,	WT_INVALID,	WT_INVALID,	WT_INVALID,	WT_INVALID,		WT_INVALID    }		// TEX_SKIRT_BAKED -}; - -const LLUUID BAKED_TEXTURE_HASH[BAKED_TEXTURE_COUNT] =  -{ -	LLUUID("18ded8d6-bcfc-e415-8539-944c0f5ea7a6"), -	LLUUID("338c29e3-3024-4dbb-998d-7c04cf4fa88f"), -	LLUUID("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f"), -	LLUUID("b2cf28af-b840-1071-3c6a-78085d8128b5"), -	LLUUID("ea800387-ea1a-14e0-56cb-24f2022f969a") -}; -  // The agent instance.  LLAgent gAgent; @@ -424,8 +406,8 @@ LLAgent::LLAgent() :  		mControlsTakenPassedOnCount[i] = 0;  	} -	mActiveCacheQueries = new S32[BAKED_TEXTURE_COUNT]; -	for (i = 0; i < (U32)BAKED_TEXTURE_COUNT; i++) +	mActiveCacheQueries = new S32[BAKED_NUM_INDICES]; +	for (i = 0; i < (U32)BAKED_NUM_INDICES; i++)  	{  		mActiveCacheQueries[i] = 0;  	} @@ -5756,11 +5738,11 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *  		mesgsys->getU8Fast(_PREHASH_WearableData, _PREHASH_TextureIndex, texture_index, texture_block);  		if (texture_id.notNull()  -			&& (S32)texture_index < BAKED_TEXTURE_COUNT  +			&& (S32)texture_index < BAKED_NUM_INDICES   			&& gAgent.mActiveCacheQueries[ texture_index ] == query_id)  		{  			//llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl; -			avatarp->setCachedBakedTexture((LLVOAvatar::ETextureIndex)LLVOAvatar::sBakedTextureIndices[texture_index], texture_id); +			avatarp->setCachedBakedTexture(getTextureIndex((EBakedTextureIndex)texture_index), texture_id);  			//avatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id );  			gAgent.mActiveCacheQueries[ texture_index ] = 0;  			num_results++; @@ -7053,11 +7035,8 @@ void LLAgent::sendAgentSetAppearance()  		return;  	} -	llinfos << "TAT: Sent AgentSetAppearance: " << -		(( mAvatarObject->getTEImage( LLVOAvatar::TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR )  ? "HEAD " : "head " ) << -		(( mAvatarObject->getTEImage( LLVOAvatar::TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "UPPER " : "upper " ) << -		(( mAvatarObject->getTEImage( LLVOAvatar::TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "LOWER " : "lower " ) << -		(( mAvatarObject->getTEImage( LLVOAvatar::TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR )  ? "EYES" : "eyes" ) << llendl; + +	llinfos << "TAT: Sent AgentSetAppearance: " << mAvatarObject->getBakedStatusForPrintout() << llendl;  	//dumpAvatarTEs( "sendAgentSetAppearance()" );  	LLMessageSystem* msg = gMessageSystem; @@ -7071,7 +7050,7 @@ void LLAgent::sendAgentSetAppearance()  	// NOTE -- when we start correcting all of the other Havok geometry   	// to compensate for the COLLISION_TOLERANCE ugliness we will have   	// to tweak this number again -	LLVector3 body_size = mAvatarObject->mBodySize; +	const LLVector3 body_size = mAvatarObject->mBodySize;  	msg->addVector3Fast(_PREHASH_Size, body_size);	  	// To guard against out of order packets @@ -7083,19 +7062,18 @@ void LLAgent::sendAgentSetAppearance()  	// KLW - TAT this will probably need to check the local queue.  	BOOL textures_current = !mAvatarObject->hasPendingBakedUploads() && mWearablesLoaded; -	S32 baked_texture_index; -	for( baked_texture_index = 0; baked_texture_index < BAKED_TEXTURE_COUNT; baked_texture_index++ ) +	for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )  	{ -		S32 tex_index = LLVOAvatar::sBakedTextureIndices[baked_texture_index]; +		const ETextureIndex texture_index = getTextureIndex((EBakedTextureIndex)baked_index);  		// if we're not wearing a skirt, we don't need the texture to be baked -		if (tex_index == LLVOAvatar::TEX_SKIRT_BAKED && !mAvatarObject->isWearingWearableType(WT_SKIRT)) +		if (texture_index == TEX_SKIRT_BAKED && !mAvatarObject->isWearingWearableType(WT_SKIRT))  		{  			continue;  		}  		// IMG_DEFAULT_AVATAR means not baked -		if (mAvatarObject->getTEImage( tex_index)->getID() == IMG_DEFAULT_AVATAR) +		if (!mAvatarObject->isTextureDefined(texture_index))  		{  			textures_current = FALSE;  			break; @@ -7106,50 +7084,56 @@ void LLAgent::sendAgentSetAppearance()  	if (textures_current)  	{  		llinfos << "TAT: Sending cached texture data" << llendl; -		for (baked_texture_index = 0; baked_texture_index < BAKED_TEXTURE_COUNT; baked_texture_index++) +		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)  		{ +			const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index);  			LLUUID hash; - -			for( S32 wearable_num = 0; wearable_num < MAX_WEARABLES_PER_LAYERSET; wearable_num++ ) +			for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++)  			{ -				EWearableType wearable_type = WEARABLE_BAKE_TEXTURE_MAP[baked_texture_index][wearable_num]; - -				LLWearable* wearable = getWearable( wearable_type ); +				// EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num]; +				const EWearableType wearable_type = wearable_dict->mWearablesVec[i]; +				const LLWearable* wearable = getWearable(wearable_type);  				if (wearable)  				{  					hash ^= wearable->getID();  				}  			} -  			if (hash.notNull())  			{ -				hash ^= BAKED_TEXTURE_HASH[baked_texture_index]; +				hash ^= wearable_dict->mHashID;  			} -			S32 tex_index = LLVOAvatar::sBakedTextureIndices[baked_texture_index]; +			const ETextureIndex texture_index = getTextureIndex((EBakedTextureIndex)baked_index);  			msg->nextBlockFast(_PREHASH_WearableData);  			msg->addUUIDFast(_PREHASH_CacheID, hash); -			msg->addU8Fast(_PREHASH_TextureIndex, (U8)tex_index); +			msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);  		} +		msg->nextBlockFast(_PREHASH_ObjectData); +		mAvatarObject->packTEMessage( gMessageSystem ); +	} +	else +	{ +		// If the textures aren't baked, send NULL for texture IDs +		// This means the baked texture IDs on the server will be untouched. +		// Once all textures are baked, another AvatarAppearance message will be sent to update the TEs +		msg->nextBlockFast(_PREHASH_ObjectData); +		gMessageSystem->addBinaryDataFast(_PREHASH_TextureEntry, NULL, 0);  	} -	msg->nextBlockFast(_PREHASH_ObjectData); -	mAvatarObject->packTEMessage( gMessageSystem );  	S32 transmitted_params = 0;  	for (LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarObject->getFirstVisualParam();  		 param;  		 param = (LLViewerVisualParam*)mAvatarObject->getNextVisualParam())  	{ -		F32 param_value = param->getWeight(); -	  		if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)  		{  			msg->nextBlockFast(_PREHASH_VisualParam );  			// We don't send the param ids.  Instead, we assume that the receiver has the same params in the same sequence. -			U8 new_weight = F32_to_U8(param_value, param->getMinWeight(), param->getMaxWeight()); +			const F32 param_value = param->getWeight(); +			const U8 new_weight = F32_to_U8(param_value, param->getMinWeight(), param->getMaxWeight());  			msg->addU8Fast(_PREHASH_ParamValue, new_weight );  			transmitted_params++;  		} @@ -7388,8 +7372,6 @@ void LLAgent::setWearableOutfit(  		wearables[i]->writeToAvatar( TRUE );  	} -	LLFloaterCustomize::setCurrentWearableType( WT_SHAPE ); -  	// Start rendering & update the server  	mWearablesLoaded = TRUE;   	sendAgentWearablesUpdate(); @@ -7511,14 +7493,15 @@ void LLAgent::queryWearableCache()  	gMessageSystem->addS32Fast(_PREHASH_SerialNum, mTextureCacheQueryID);  	S32 num_queries = 0; -	for (S32 baked_texture_index = 0; baked_texture_index < BAKED_TEXTURE_COUNT; baked_texture_index++) +	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )  	{ +		const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index);  		LLUUID hash; -		for (S32 wearable_num = 0; wearable_num < MAX_WEARABLES_PER_LAYERSET; wearable_num++) +		for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++)  		{ -			EWearableType wearable_type = WEARABLE_BAKE_TEXTURE_MAP[baked_texture_index][wearable_num]; -				 -			LLWearable* wearable = getWearable( wearable_type ); +			// EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num]; +			const EWearableType wearable_type = wearable_dict->mWearablesVec[i]; +			const LLWearable* wearable = getWearable(wearable_type);  			if (wearable)  			{  				hash ^= wearable->getID(); @@ -7526,17 +7509,17 @@ void LLAgent::queryWearableCache()  		}  		if (hash.notNull())  		{ -			hash ^= BAKED_TEXTURE_HASH[baked_texture_index]; +			hash ^= wearable_dict->mHashID;  			num_queries++;  			// *NOTE: make sure at least one request gets packed -			//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_texture_index << llendl; +			//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;  			gMessageSystem->nextBlockFast(_PREHASH_WearableData);  			gMessageSystem->addUUIDFast(_PREHASH_ID, hash); -			gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_texture_index); +			gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index);  		} -		mActiveCacheQueries[ baked_texture_index ] = mTextureCacheQueryID; +		mActiveCacheQueries[ baked_index ] = mTextureCacheQueryID;  	}  	llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl; @@ -7563,7 +7546,7 @@ void LLAgent::userRemoveAllClothes( void* userdata )  	// We have to do this up front to avoid having to deal with the case of multiple wearables being dirty.  	if( gFloaterCustomize )  	{ -		gFloaterCustomize->askToSaveAllIfDirty( LLAgent::userRemoveAllClothesStep2, NULL ); +		gFloaterCustomize->askToSaveIfDirty( LLAgent::userRemoveAllClothesStep2, NULL );  	}  	else  	{ diff --git a/indra/newview/llappearance.h b/indra/newview/llappearance.h index 949b9e59fc..9018150146 100644 --- a/indra/newview/llappearance.h +++ b/indra/newview/llappearance.h @@ -44,14 +44,14 @@ public:  	void	addParam( S32 id, F32 value )				{ mParamMap[id] = value; }  	F32		getParam( S32 id, F32 defval )				{ return get_if_there(mParamMap, id, defval ); } -	void	addTexture( S32 te, const LLUUID& uuid )	{ if( te < LLVOAvatar::TEX_NUM_ENTRIES ) mTextures[te] = uuid; } -	const LLUUID& getTexture( S32 te )					{ return ( te < LLVOAvatar::TEX_NUM_ENTRIES ) ? mTextures[te] : LLUUID::null; } +	void	addTexture( S32 te, const LLUUID& uuid )	{ if( te < LLVOAvatarDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; } +	const LLUUID& getTexture( S32 te )					{ return ( te < LLVOAvatarDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; } -	void	clear()										{ mParamMap.clear(); for( S32 i=0; i<LLVOAvatar::TEX_NUM_ENTRIES; i++ ) mTextures[i].setNull(); } +	void	clear()										{ mParamMap.clear(); for( S32 i=0; i<LLVOAvatarDefines::TEX_NUM_INDICES; i++ ) mTextures[i].setNull(); }  	typedef std::map<S32, F32> param_map_t;  	param_map_t mParamMap; -	LLUUID	mTextures[LLVOAvatar::TEX_NUM_ENTRIES]; +	LLUUID	mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];  };  #endif  // LL_LLAPPEARANCE_H diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 9dd0668787..481a6ceb26 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -56,6 +56,7 @@  #include "llviewerobjectlist.h"  #include "llviewermenufile.h"  #include "llviewerwindow.h" +#include "lltexlayer.h"  // When uploading multiple files, don't display any of them when uploading more than this number.  static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5; @@ -139,6 +140,7 @@ void LLAssetUploadResponder::result(const LLSD& content)  		if (mFileName.empty())  		{  			// rename the file in the VFS to the actual asset id +			// llinfos << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << llendl;  			gVFS->renameFile(mVFileID, mAssetType, content["new_asset"].asUUID(), mAssetType);  		}  		uploadComplete(content); @@ -332,6 +334,48 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)  	}  } +LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data, +														   const LLUUID& vfile_id, +														   LLAssetType::EType asset_type, +														   LLBakedUploadData * baked_upload_data) +												: LLAssetUploadResponder(post_data, vfile_id, asset_type), +												mBakedUploadData(baked_upload_data) +{ +} + +LLSendTexLayerResponder::~LLSendTexLayerResponder() +{ +	// mBakedUploadData is normally deleted by calls to LLTexLayerSetBuffer::onTextureUploadComplete() below +	if (mBakedUploadData) +	{	// ...but delete it in the case where uploadComplete() is never called +		delete mBakedUploadData; +		mBakedUploadData = NULL; +	} +} + + +// Baked texture upload completed +void LLSendTexLayerResponder::uploadComplete(const LLSD& content) +{ +	LLUUID item_id = mPostData["item_id"]; + +	std::string result = content["state"]; +	LLUUID new_id = content["new_asset"]; + +	llinfos << "LLSendTexLayerResponder::result from capabilities: " << result << llendl; +	if (result == "complete" +		&& mBakedUploadData != NULL) +	{	// Invoke  +		LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE); +		mBakedUploadData = NULL;	// deleted in onTextureUploadComplete() +	} +	else +	{	// Invoke the original callback with an error result +		LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); +		mBakedUploadData = NULL;	// deleted in onTextureUploadComplete() +	} +} +  LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,  																 const LLUUID& vfile_id, diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index 42b3a9d27d..9ab571ae99 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -71,6 +71,22 @@ public:  	virtual void uploadComplete(const LLSD& content);  }; +class LLBakedUploadData; +class LLSendTexLayerResponder : public LLAssetUploadResponder +{ +public: +	LLSendTexLayerResponder(const LLSD& post_data, +							const LLUUID& vfile_id, +							LLAssetType::EType asset_type, +							LLBakedUploadData * baked_upload_data); + +	~LLSendTexLayerResponder(); + +	virtual void uploadComplete(const LLSD& content); + +	LLBakedUploadData * mBakedUploadData; +}; +  class LLUpdateAgentInventoryResponder : public LLAssetUploadResponder  {  public: diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 9db9197500..0de21f03f2 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -758,7 +758,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  			avatarp->renderCollisionVolumes();  		} -		if (avatarp->mIsSelf && LLAgent::sDebugDisplayTarget) +		if (avatarp->isSelf() && LLAgent::sDebugDisplayTarget)  		{  			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  			LLVector3 pos = avatarp->getPositionAgent(); diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 0dc95ff536..1e2630e1fb 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -114,7 +114,12 @@ public:  	static BOOL sSkipTransparent;  }; - +class LLVertexBufferAvatar : public LLVertexBuffer +{ +public: +	LLVertexBufferAvatar(); +	virtual void setupVertexBuffer(U32 data_mask) const; +};  extern S32 AVATAR_OFFSET_POS;  extern S32 AVATAR_OFFSET_NORMAL; diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 747b685b5e..162456b8ce 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -1041,7 +1041,7 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLDynamicTexture  	mDummyAvatar->updateJointLODs();  	mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);  	mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET); -	mDummyAvatar->mSkirtLOD.setVisible(FALSE, TRUE); +	mDummyAvatar->hideSkirt();  	gPipeline.markVisible(mDummyAvatar->mDrawable, *LLViewerCamera::getInstance());  	// stop extraneous animations diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 6ff34fbfb9..e81b5d7fce 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -40,6 +40,8 @@  #include "llviewerobjectlist.h"  #include "llvoavatar.h" +using namespace LLVOAvatarDefines; +  LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLUUID& id) :   	LLFloater(std::string("avatar_texture_debug")),  	mID(id) @@ -68,26 +70,11 @@ LLFloaterAvatarTextures* LLFloaterAvatarTextures::show(const LLUUID &id)  BOOL LLFloaterAvatarTextures::postBuild()  { -	mBakedHead = getChild<LLTextureCtrl>("baked_head"); -	mBakedEyes = getChild<LLTextureCtrl>("baked_eyes"); -	mBakedUpper = getChild<LLTextureCtrl>("baked_upper_body"); -	mBakedLower = getChild<LLTextureCtrl>("baked_lower_body"); -	mBakedSkirt = getChild<LLTextureCtrl>("baked_skirt"); -	mHair = getChild<LLTextureCtrl>("hair"); -	mMakeup = getChild<LLTextureCtrl>("head_bodypaint"); -	mEye = getChild<LLTextureCtrl>("eye_texture"); -	mShirt = getChild<LLTextureCtrl>("shirt"); -	mUpperTattoo = getChild<LLTextureCtrl>("upper_bodypaint"); -	mUpperJacket = getChild<LLTextureCtrl>("upper_jacket"); -	mGloves = getChild<LLTextureCtrl>("gloves"); -	mUndershirt = getChild<LLTextureCtrl>("undershirt"); -	mPants = getChild<LLTextureCtrl>("pants"); -	mLowerTattoo = getChild<LLTextureCtrl>("lower_bodypaint"); -	mShoes = getChild<LLTextureCtrl>("shoes"); -	mSocks = getChild<LLTextureCtrl>("socks"); -	mJacket = getChild<LLTextureCtrl>("jacket"); -	mUnderpants = getChild<LLTextureCtrl>("underpants"); -	mSkirt = getChild<LLTextureCtrl>("skirt_texture"); +	for (U32 i=0; i < TEX_NUM_INDICES; i++) +	{ +		const std::string tex_name = LLVOAvatarDictionary::getInstance()->getTexture(ETextureIndex(i))->mName; +		mTextures[i] = getChild<LLTextureCtrl>(tex_name); +	}  	mTitle = getTitle();  	childSetAction("Dump", onClickDump, this); @@ -105,7 +92,7 @@ void LLFloaterAvatarTextures::draw()  #if !LL_RELEASE_FOR_DOWNLOAD  static void update_texture_ctrl(LLVOAvatar* avatarp,  								 LLTextureCtrl* ctrl, -								 LLVOAvatar::ETextureIndex te) +								 ETextureIndex te)  {  	LLUUID id = avatarp->getTE(te)->getID();  	if (id == IMG_DEFAULT_AVATAR) @@ -148,29 +135,10 @@ void LLFloaterAvatarTextures::refresh()  		{  			setTitle(mTitle + ": " + fullname);  		} -		update_texture_ctrl(avatarp, mBakedHead,	LLVOAvatar::TEX_HEAD_BAKED); -		update_texture_ctrl(avatarp, mBakedEyes,	LLVOAvatar::TEX_EYES_BAKED); -		update_texture_ctrl(avatarp, mBakedUpper,	LLVOAvatar::TEX_UPPER_BAKED); -		update_texture_ctrl(avatarp, mBakedLower,	LLVOAvatar::TEX_LOWER_BAKED); -		update_texture_ctrl(avatarp, mBakedSkirt,	LLVOAvatar::TEX_SKIRT_BAKED); - -		update_texture_ctrl(avatarp, mMakeup,		LLVOAvatar::TEX_HEAD_BODYPAINT); -		update_texture_ctrl(avatarp, mHair,			LLVOAvatar::TEX_HAIR); -		update_texture_ctrl(avatarp, mEye,			LLVOAvatar::TEX_EYES_IRIS); - -		update_texture_ctrl(avatarp, mShirt,		LLVOAvatar::TEX_UPPER_SHIRT); -		update_texture_ctrl(avatarp, mUpperTattoo,	LLVOAvatar::TEX_UPPER_BODYPAINT); -		update_texture_ctrl(avatarp, mUpperJacket,	LLVOAvatar::TEX_UPPER_JACKET); -		update_texture_ctrl(avatarp, mGloves,		LLVOAvatar::TEX_UPPER_GLOVES); -		update_texture_ctrl(avatarp, mUndershirt,	LLVOAvatar::TEX_UPPER_UNDERSHIRT); - -		update_texture_ctrl(avatarp, mPants,		LLVOAvatar::TEX_LOWER_PANTS); -		update_texture_ctrl(avatarp, mLowerTattoo,	LLVOAvatar::TEX_LOWER_BODYPAINT); -		update_texture_ctrl(avatarp, mShoes,		LLVOAvatar::TEX_LOWER_SHOES); -		update_texture_ctrl(avatarp, mSocks,		LLVOAvatar::TEX_LOWER_SOCKS); -		update_texture_ctrl(avatarp, mJacket,		LLVOAvatar::TEX_LOWER_JACKET); -		update_texture_ctrl(avatarp, mUnderpants,	LLVOAvatar::TEX_LOWER_UNDERPANTS); -		update_texture_ctrl(avatarp, mSkirt,		LLVOAvatar::TEX_SKIRT); +		for (U32 i=0; i < TEX_NUM_INDICES; i++) +		{ +			update_texture_ctrl(avatarp, mTextures[i], ETextureIndex(i)); +		}  	}  	else  	{ diff --git a/indra/newview/llfloateravatartextures.h b/indra/newview/llfloateravatartextures.h index fbcf47bf7d..4138edeb4d 100644 --- a/indra/newview/llfloateravatartextures.h +++ b/indra/newview/llfloateravatartextures.h @@ -36,6 +36,7 @@  #include "llfloater.h"  #include "lluuid.h"  #include "llstring.h" +#include "llvoavatardefines.h"  class LLTextureCtrl; @@ -58,26 +59,7 @@ private:  private:  	LLUUID	mID;  	std::string mTitle; -	LLTextureCtrl* mBakedHead; -	LLTextureCtrl* mBakedEyes; -	LLTextureCtrl* mBakedUpper; -	LLTextureCtrl* mBakedLower; -	LLTextureCtrl* mBakedSkirt; -	LLTextureCtrl* mHair; -	LLTextureCtrl* mMakeup; -	LLTextureCtrl* mEye; -	LLTextureCtrl* mShirt; -	LLTextureCtrl* mUpperTattoo; -	LLTextureCtrl* mUpperJacket; -	LLTextureCtrl* mGloves; -	LLTextureCtrl* mUndershirt; -	LLTextureCtrl* mPants; -	LLTextureCtrl* mLowerTattoo; -	LLTextureCtrl* mShoes; -	LLTextureCtrl* mSocks; -	LLTextureCtrl* mJacket; -	LLTextureCtrl* mUnderpants; -	LLTextureCtrl* mSkirt; +	LLTextureCtrl* mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];  };  #endif diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 2e59240c49..6497821349 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -1072,16 +1072,20 @@ void LLHUDText::renderAllHUD()  	LLGLState::checkStates();  	LLGLState::checkTextureChannels();  	LLGLState::checkClientArrays(); -	 -	LLGLEnable color_mat(GL_COLOR_MATERIAL); -	LLGLDepthTest depth(GL_FALSE, GL_FALSE); -	 -	VisibleTextObjectIterator text_it; -	for (text_it = sVisibleHUDTextObjects.begin(); text_it != sVisibleHUDTextObjects.end(); ++text_it)  	{ -		(*text_it)->renderText(FALSE); +		LLGLEnable color_mat(GL_COLOR_MATERIAL); +		LLGLDepthTest depth(GL_FALSE, GL_FALSE); +		 +		VisibleTextObjectIterator text_it; + +		for (text_it = sVisibleHUDTextObjects.begin(); text_it != sVisibleHUDTextObjects.end(); ++text_it) +		{ +			(*text_it)->renderText(FALSE); +		}  	} +	 +	LLVertexBuffer::unbind();  	LLGLState::checkStates();  	LLGLState::checkTextureChannels(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 3ac7deb3df..0aa406dff1 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3883,7 +3883,7 @@ void wear_inventory_category_on_avatar( LLInventoryCategory* category, BOOL appe  	if( gFloaterCustomize )  	{ -		gFloaterCustomize->askToSaveAllIfDirty( +		gFloaterCustomize->askToSaveIfDirty(  			wear_inventory_category_on_avatar_step2,  			userdata);  	} @@ -4154,7 +4154,7 @@ void remove_inventory_category_from_avatar( LLInventoryCategory* category )  	if( gFloaterCustomize )  	{ -		gFloaterCustomize->askToSaveAllIfDirty( +		gFloaterCustomize->askToSaveIfDirty(  			remove_inventory_category_from_avatar_step2,  			uuid);  	} diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 031f4ab304..cdcd68de38 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -241,7 +241,7 @@ void LLProgressView::onCancelButtonClicked(void*)  void LLProgressView::onClickMessage(void* data)  {  	LLProgressView* viewp = (LLProgressView*)data; -	if ( ! viewp->mMessage.empty() ) +	if ( viewp != NULL && ! viewp->mMessage.empty() )  	{  		std::string url_to_open( "" ); diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 6a7ba7b7f4..b376eed814 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -47,6 +47,7 @@  #include "llvfile.h"  #include "llviewerimagelist.h"  #include "llviewerimagelist.h" +#include "llviewerregion.h"  #include "llviewerstats.h"  #include "llviewerwindow.h"  #include "llvoavatar.h" @@ -54,9 +55,12 @@  #include "pipeline.h"  #include "v4coloru.h"  #include "llrender.h" +#include "llassetuploadresponders.h"  //#include "../tools/imdebug/imdebug.h" +using namespace LLVOAvatarDefines; +  // static  S32 LLTexLayerSetBuffer::sGLByteCount = 0;  S32 LLTexLayerSetBuffer::sGLBumpByteCount = 0; @@ -64,11 +68,12 @@ S32 LLTexLayerSetBuffer::sGLBumpByteCount = 0;  //-----------------------------------------------------------------------------  // LLBakedUploadData()  //----------------------------------------------------------------------------- -LLBakedUploadData::LLBakedUploadData( LLVOAvatar* avatar, LLTexLayerSetBuffer* layerset_buffer ) :  +LLBakedUploadData::LLBakedUploadData( LLVOAvatar* avatar, LLTexLayerSetBuffer* layerset_buffer, const LLUUID & id ) :   	mAvatar( avatar ), -	mLayerSetBuffer( layerset_buffer ) +	mLayerSetBuffer( layerset_buffer ), +	mID(id)  {  -	mID.generate(); +	mStartTime = LLFrameTimer::getTotalTime();		// Record starting time  	for( S32 i = 0; i < WT_COUNT; i++ )  	{  		LLWearable* wearable = gAgent.getWearable( (EWearableType)i); @@ -221,7 +226,7 @@ BOOL LLTexLayerSetBuffer::needsRender()  	BOOL needs_update = gAgent.mNumPendingQueries == 0 && (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating;  	if (needs_update)  	{ -		BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == LLVOAvatar::TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT); +		BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT);  		if (invalid_skirt)  		{  			// we were trying to create a skirt texture @@ -393,7 +398,7 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)  					baked_image_data[5*i + 0] = baked_color_data[4*i + 0];  					baked_image_data[5*i + 1] = baked_color_data[4*i + 1];  					baked_image_data[5*i + 2] = baked_color_data[4*i + 2]; -					baked_image_data[5*i + 3] = baked_color_data[4*i + 3] < 255 ? baked_color_data[4*i + 3] : baked_bump_data[4*i]; +					baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes.  					baked_image_data[5*i + 4] = baked_mask_data[i];  					i++;  				} @@ -409,7 +414,7 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)  					baked_image_data[5*i + 0] = baked_color_data[4*i + 0];  					baked_image_data[5*i + 1] = baked_color_data[4*i + 1];  					baked_image_data[5*i + 2] = baked_color_data[4*i + 2]; -					baked_image_data[5*i + 3] = baked_bump_data[4*i]; +					baked_image_data[5*i + 3] = 255; // reserve for alpha   					baked_image_data[5*i + 4] = baked_mask_data[i];  					i++;  				} @@ -418,7 +423,7 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)  	}  	else  	{	 -		if (mTexLayerSet->getBodyRegion() == "skirt") +		if (mTexLayerSet->getBodyRegion() == "skirt" || mTexLayerSet->getBodyRegion() == "hair")  		{  			S32 i = 0;  			for( S32 u = 0; u < mWidth; u++ ) @@ -443,7 +448,7 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)  					baked_image_data[4*i + 0] = baked_color_data[4*i + 0];  					baked_image_data[4*i + 1] = baked_color_data[4*i + 1];  					baked_image_data[4*i + 2] = baked_color_data[4*i + 2]; -					baked_image_data[4*i + 3] = baked_mask_data[i]; +					baked_image_data[4*i + 3] = 255; // eyes should have no mask - reserve for alpha   					i++;  				}  			} @@ -479,16 +484,34 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)  			if( valid )  			{ -				LLBakedUploadData* baked_upload_data = new LLBakedUploadData( gAgent.getAvatarObject(), this ); -				mUploadID = baked_upload_data->mID; - -				gAssetStorage->storeAssetData(tid, -											  LLAssetType::AT_TEXTURE, -											  LLTexLayerSetBuffer::onTextureUploadComplete, -											  baked_upload_data, -											  TRUE,		// temp_file -											  FALSE,	// is_priority -											  TRUE);	// store_local +				// baked_upload_data is owned by the responder and deleted after the request completes +				LLBakedUploadData* baked_upload_data = new LLBakedUploadData( gAgent.getAvatarObject(), this, asset_id ); +				mUploadID = asset_id; +				 +				// upload the image +				std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture"); + +				if(!url.empty() +					&& !LLPipeline::sForceOldBakedUpload) // Toggle the debug setting UploadBakedTexOld to change between the new caps method and old method +				{ +					llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl; + +					LLSD body = LLSD::emptyMap(); +					LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data)); +					// Responder will call LLTexLayerSetBuffer::onTextureUploadComplete() +				}  +				else +				{ +					llinfos << "Baked texture upload via Asset Store." <<  llendl; +					// gAssetStorage->storeAssetData(mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)this, FALSE); +					gAssetStorage->storeAssetData(tid, +												  LLAssetType::AT_TEXTURE, +												  LLTexLayerSetBuffer::onTextureUploadComplete, +												  baked_upload_data, +												  TRUE,		// temp_file +												  TRUE,		// is_priority +												  TRUE);	// store_local +				}  				mNeedsUpload = FALSE;  			} @@ -541,15 +564,10 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* user  				if( result >= 0 )  				{ -					LLVOAvatar::ETextureIndex baked_te = avatar->getBakedTE( layerset_buffer->mTexLayerSet ); -					if( !gAgent.cameraCustomizeAvatar() ) -					{ -						avatar->setNewBakedTexture( baked_te, uuid ); -					} -					else -					{ -						llinfos << "LLTexLayerSetBuffer::onTextureUploadComplete() when in Customize Avatar" << llendl; -					} +					ETextureIndex baked_te = avatar->getBakedTE( layerset_buffer->mTexLayerSet ); +					U64 now = LLFrameTimer::getTotalTime();		// Record starting time +					llinfos << "Baked texture upload took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl; +					avatar->setNewBakedTexture( baked_te, uuid );  				}  				else  				{ @@ -800,6 +818,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )  			{  				LLGLSUIDefault gls_ui;  				gGL.getTexUnit(0)->bind(image_gl); +				gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );  				gl_rect_2d_simple_tex( width, height );  			}  			else @@ -807,9 +826,10 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )  				success = FALSE;  			}  		} +		gGL.flush();  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -		gGL.flush(); +		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);  		gGL.setColorMask(true, true);  		gGL.setSceneBlendType(LLRender::BT_ALPHA);  	} @@ -895,7 +915,7 @@ void LLTexLayerSet::createComposite()  		S32 width = mInfo->mWidth;  		S32 height = mInfo->mHeight;  		// Composite other avatars at reduced resolution -		if( !mAvatar->mIsSelf ) +		if( !mAvatar->isSelf() )  		{  			width /= 2;  			height /= 2; @@ -1049,59 +1069,63 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)  			if( "upper_shirt" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_UPPER_SHIRT; +				mLocalTexture = TEX_UPPER_SHIRT;  			}  			else if( "upper_bodypaint" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_UPPER_BODYPAINT; +				mLocalTexture = TEX_UPPER_BODYPAINT;  			}  			else if( "lower_pants" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_LOWER_PANTS; +				mLocalTexture = TEX_LOWER_PANTS;  			}  			else if( "lower_bodypaint" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_LOWER_BODYPAINT; +				mLocalTexture = TEX_LOWER_BODYPAINT;  			}  			else if( "lower_shoes" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_LOWER_SHOES; +				mLocalTexture = TEX_LOWER_SHOES;  			}  			else if( "head_bodypaint" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_HEAD_BODYPAINT; +				mLocalTexture = TEX_HEAD_BODYPAINT;  			}  			else if( "lower_socks" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_LOWER_SOCKS; +				mLocalTexture = TEX_LOWER_SOCKS;  			}  			else if( "upper_jacket" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_UPPER_JACKET; +				mLocalTexture = TEX_UPPER_JACKET;  			}  			else if( "lower_jacket" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_LOWER_JACKET; +				mLocalTexture = TEX_LOWER_JACKET;  			}  			else if( "upper_gloves" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_UPPER_GLOVES; +				mLocalTexture = TEX_UPPER_GLOVES;  			}  			else if( "upper_undershirt" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_UPPER_UNDERSHIRT; +				mLocalTexture = TEX_UPPER_UNDERSHIRT;  			}  			else if( "lower_underpants" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_LOWER_UNDERPANTS; +				mLocalTexture = TEX_LOWER_UNDERPANTS;  			}  			else if( "eyes_iris" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_EYES_IRIS; +				mLocalTexture = TEX_EYES_IRIS;  			}  			else if( "skirt" == local_texture )  			{ -				mLocalTexture = LLVOAvatar::LOCTEX_SKIRT; +				mLocalTexture = TEX_SKIRT; +			}			 +			else if( "hair_grain" == local_texture ) +			{ +				mLocalTexture = TEX_HAIR;  			}  			else  			{ @@ -1364,7 +1388,7 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )  	{  		{  			LLImageGL* image_gl = NULL; -			if( mTexLayerSet->getAvatar()->getLocalTextureGL( getInfo()->mLocalTexture, &image_gl ) ) +			if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )  			{  				if( image_gl )  				{ @@ -1434,7 +1458,7 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )  U8*	LLTexLayer::getAlphaData()  {  	LLCRC alpha_mask_crc; -	const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID(getInfo()->mLocalTexture); +	const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture);  	alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES);  	for( alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ ) @@ -1563,7 +1587,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4  	{  		{  			LLImageGL* image_gl = NULL; -			if( mTexLayerSet->getAvatar()->getLocalTextureGL( getInfo()->mLocalTexture, &image_gl ) ) +			if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )  			{  				if( image_gl && (image_gl->getComponents() == 4) )  				{ @@ -1627,7 +1651,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4  	if (!mMorphMasksValid && !mMaskedMorphs.empty())  	{  		LLCRC alpha_mask_crc; -		const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID(getInfo()->mLocalTexture); +		const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture);  		alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES);  		for( alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ ) @@ -1648,7 +1672,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4  		else  		{  			// clear out a slot if we have filled our cache -			S32 max_cache_entries = getTexLayerSet()->getAvatar()->mIsSelf ? 4 : 1; +			S32 max_cache_entries = getTexLayerSet()->getAvatar()->isSelf() ? 4 : 1;  			while ((S32)mAlphaCache.size() >= max_cache_entries)  			{  				iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry @@ -1701,7 +1725,7 @@ BOOL LLTexLayer::renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 i  		format = GL_ALPHA;  	} -	if( (in_width != VOAVATAR_SCRATCH_TEX_WIDTH) || (in_height != VOAVATAR_SCRATCH_TEX_HEIGHT) ) +	if( (in_width != SCRATCH_TEX_WIDTH) || (in_height != SCRATCH_TEX_HEIGHT) )  	{  		LLGLSNoAlphaTest gls_no_alpha_test; @@ -1918,8 +1942,13 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL set_by_user)  		LLVOAvatar* avatar = mTexLayer->getTexLayerSet()->getAvatar();  		if( avatar->getSex() & getSex() )  		{ +			if ( gAgent.cameraCustomizeAvatar() ) +			{ +				set_by_user = FALSE; +			}  			avatar->invalidateComposite( mTexLayer->getTexLayerSet(), set_by_user );  			mTexLayer->invalidateMorphMasks(); +			avatar->updateMeshTextures();  		}  	}  } @@ -2053,7 +2082,7 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )  		// Don't keep the cache for other people's avatars  		// (It's not really a "cache" in that case, but the logic is the same) -		if( !mTexLayer->getTexLayerSet()->getAvatar()->mIsSelf ) +		if( !mTexLayer->getTexLayerSet()->getAvatar()->isSelf() )  		{  			mCachedProcessedImageGL = NULL;  		} diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index 5ab8c91f72..18e6d6b24f 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -537,13 +537,14 @@ public:  class LLBakedUploadData  {  public: -	LLBakedUploadData( LLVOAvatar* avatar, LLTexLayerSetBuffer* layerset_buffer ); +	LLBakedUploadData( LLVOAvatar* avatar, LLTexLayerSetBuffer* layerset_buffer, const LLUUID & id);  	~LLBakedUploadData() {}  	LLUUID					mID;  	LLVOAvatar*				mAvatar;	 // just backlink, don't LLPointer   	LLTexLayerSetBuffer*	mLayerSetBuffer;  	LLUUID					mWearableAssets[WT_COUNT]; +	U64						mStartTime;		// Used to measure time baked texture upload requires  };  extern LLTexStaticImageList gTexStaticImageList; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index db864765b1..fcad86e498 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -955,7 +955,7 @@ void LLToolDragAndDrop::pickCallback(const LLPickInfo& pick_info)  		if(hit_obj->isAvatar())  		{ -			if(((LLVOAvatar*) hit_obj)->mIsSelf) +			if(((LLVOAvatar*) hit_obj)->isSelf())  			{  				target = DT_SELF;  				hit_face = -1; diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index 6069f1ffc6..351c02b4c0 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -221,7 +221,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)  			gViewerWindow->getLeftMouseDown() &&   			!gSavedSettings.getBOOL("FreezeTime") &&  			(hit_obj == gAgent.getAvatarObject() ||  -				(hit_obj && hit_obj->isAttachment() && LLVOAvatar::findAvatarFromAttachment(hit_obj)->mIsSelf))) +				(hit_obj && hit_obj->isAttachment() && LLVOAvatar::findAvatarFromAttachment(hit_obj)->isSelf())))  		{  			LLToolCamera::getInstance()->mMouseSteering = TRUE;  		} diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index f15f0f44b0..75e19645a6 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -237,7 +237,11 @@ BOOL LLVisualParamHint::render()  	{  		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();  		LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); +		gGL.setAlphaRejectSettings(LLRender::CF_ALWAYS); +		gGL.setSceneBlendType(LLRender::BT_REPLACE);  		avatarPoolp->renderAvatars(avatarp);  // renders only one avatar +		gGL.setSceneBlendType(LLRender::BT_ALPHA); +		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  	}  	avatarp->setVisualParamWeight(mVisualParam, mLastParamWeight);  	gGL.color4f(1,1,1,1); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 6b99cfbeaf..c0d3466fab 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -119,6 +119,12 @@ static bool handleSetShaderChanged(const LLSD& newvalue)  	return true;  } +static bool handleSetSelfInvisible( const LLSD& newvalue) +{ +	LLVOAvatar::onChangeSelfInvisible( newvalue.asBoolean() ); +	return true; +} +  static bool handleReleaseGLBufferChanged(const LLSD& newvalue)  {  	if (gPipeline.isInit()) @@ -205,16 +211,6 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue)  	return true;  } -const S32 MAX_USER_COMPOSITE_LIMIT = 100; -const S32 MIN_USER_COMPOSITE_LIMIT = 0; - -static bool handleCompositeLimitChanged(const LLSD& newvalue) -{ -	S32 composite_limit = llmax(MIN_USER_COMPOSITE_LIMIT,  llmin((S32)newvalue.asInteger(), MAX_USER_COMPOSITE_LIMIT)); -	LLVOAvatar::sMaxOtherAvatarsToComposite = composite_limit; -	return true; -} -  static bool handleVideoMemoryChanged(const LLSD& newvalue)  {  	gImageList.updateMaxResidentTexMem(newvalue.asInteger()); @@ -297,6 +293,13 @@ static bool handleUseOcclusionChanged(const LLSD& newvalue)  	return true;  } +static bool handleUploadBakedTexOldChanged(const LLSD& newvalue) +{ +	LLPipeline::sForceOldBakedUpload = newvalue.asBoolean(); +	return true; +} + +  static bool handleNumpadControlChanged(const LLSD& newvalue)  {  	if (gKeyboard) @@ -453,6 +456,7 @@ void settings_setup_listeners()  	gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));  	gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));  	gSavedSettings.getControl("RenderAvatarMaxVisible")->getSignal()->connect(boost::bind(&handleAvatarMaxVisibleChanged, _1)); +	gSavedSettings.getControl("RenderAvatarInvisible")->getSignal()->connect(boost::bind(&handleSetSelfInvisible, _1));  	gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _1));  	gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _1));  	gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _1)); @@ -474,11 +478,11 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _1));  	gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _1));  	gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); -	gSavedSettings.getControl("AvatarCompositeLimit")->getSignal()->connect(boost::bind(&handleCompositeLimitChanged, _1));  	gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _1));  	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _1));  	gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _1));  	gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _1)); +	gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _1));  	gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _1));  	gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));   	gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index 89490e08bf..1cc062dbd2 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -514,6 +514,16 @@ void LLViewerJoint::setVisible(BOOL visible, BOOL recursive)  	}  } + +void LLViewerJoint::setMeshesToChildren() +{ +	removeAllChildren(); +	for (std::vector<LLViewerJointMesh*>::iterator iter = mMeshParts.begin(); +		iter != mMeshParts.end(); iter++) +	{ +		addChild((LLViewerJointMesh *) *iter); +	} +}  //-----------------------------------------------------------------------------  // LLViewerJointCollisionVolume()  //----------------------------------------------------------------------------- diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h index 0430a91833..a07902e582 100644 --- a/indra/newview/llviewerjoint.h +++ b/indra/newview/llviewerjoint.h @@ -40,6 +40,7 @@  #include "llapr.h"  class LLFace; +class LLViewerJointMesh;  //-----------------------------------------------------------------------------  // class LLViewerJoint @@ -133,8 +134,13 @@ public:  	void setVisible( BOOL visible, BOOL recursive ); +	// Takes meshes in mMeshParts and sets each one as a child joint +	void setMeshesToChildren(); +  public:  	static BOOL	sDisableLOD; +	std::vector<LLViewerJointMesh*> mMeshParts; +	void setMeshID( S32 id ) {mMeshID = id;}  protected:  	BOOL		mValid; @@ -142,6 +148,7 @@ protected:  	F32			mMinPixelArea;  	PickName	mPickName;  	BOOL		mVisible; +	S32			mMeshID;  };  class LLViewerJointCollisionVolume : public LLViewerJoint diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 4cacc5c97b..c0e02921cf 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -558,7 +558,12 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass)  		}  		else  		{ -			llwarns << "Layerset without composite" << llendl; +			// This warning will always trigger if you've hacked the avatar to show as incomplete. +			// Ignore the warning if that's the case. +			if (!gSavedSettings.getBOOL("RenderUnloadedAvatar")) +			{ +				llwarns << "Layerset without composite" << llendl; +			}  			gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT));  		}  	} diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index de16bbf8a1..47a887e909 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -212,6 +212,7 @@  #include "lltexlayer.h" +using namespace LLVOAvatarDefines;  void init_client_menu(LLMenuGL* menu);  void init_server_menu(LLMenuGL* menu); @@ -1313,8 +1314,6 @@ void init_debug_rendering_menu(LLMenuGL* menu)  	menu->createJumpKeys();  } -extern BOOL gDebugAvatarRotation; -  void init_debug_avatar_menu(LLMenuGL* menu)  {  	LLMenuGL* sub_menu = new LLMenuGL("Grab Baked Texture"); @@ -1361,7 +1360,7 @@ void init_debug_avatar_menu(LLMenuGL* menu)  	//menu->append(new LLMenuItemToggleGL("Show Collision Plane", &LLVOAvatar::sShowFootPlane));  	menu->append(new LLMenuItemToggleGL("Show Collision Skeleton", &LLVOAvatar::sShowCollisionVolumes));  	menu->append(new LLMenuItemToggleGL( "Display Agent Target", &LLAgent::sDebugDisplayTarget)); -	menu->append(new LLMenuItemToggleGL( "Debug Rotation", &gDebugAvatarRotation)); +	menu->append(new LLMenuItemToggleGL( "Debug Rotation", &LLVOAvatar::sDebugAvatarRotation));  	menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments));  	menu->append(new LLMenuItemCallGL("Rebake Textures", handle_rebake_textures, NULL, NULL, 'R', MASK_ALT | MASK_CONTROL ));  #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -1373,11 +1372,12 @@ void init_debug_avatar_menu(LLMenuGL* menu)  void init_debug_baked_texture_menu(LLMenuGL* menu)  { -	menu->append(new LLMenuItemCallGL("Iris", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_EYES_BAKED)); -	menu->append(new LLMenuItemCallGL("Head", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_HEAD_BAKED)); -	menu->append(new LLMenuItemCallGL("Upper Body", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_UPPER_BAKED)); -	menu->append(new LLMenuItemCallGL("Lower Body", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_LOWER_BAKED)); -	menu->append(new LLMenuItemCallGL("Skirt", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_SKIRT_BAKED)); +	menu->append(new LLMenuItemCallGL("Iris", handle_grab_texture, enable_grab_texture, (void*) TEX_EYES_BAKED)); +	menu->append(new LLMenuItemCallGL("Head", handle_grab_texture, enable_grab_texture, (void*) TEX_HEAD_BAKED)); +	menu->append(new LLMenuItemCallGL("Upper Body", handle_grab_texture, enable_grab_texture, (void*) TEX_UPPER_BAKED)); +	menu->append(new LLMenuItemCallGL("Lower Body", handle_grab_texture, enable_grab_texture, (void*) TEX_LOWER_BAKED)); +	menu->append(new LLMenuItemCallGL("Skirt", handle_grab_texture, enable_grab_texture, (void*) TEX_SKIRT_BAKED)); +	menu->append(new LLMenuItemCallGL("Hair", handle_grab_texture, enable_grab_texture, (void*) TEX_HAIR_BAKED));  	menu->createJumpKeys();  } @@ -3082,7 +3082,7 @@ void handle_reset_view()  	if( (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode()) && gFloaterCustomize )  	{  		// Show dialog box if needed. -		gFloaterCustomize->askToSaveAllIfDirty( reset_view_final, NULL ); +		gFloaterCustomize->askToSaveIfDirty( reset_view_final, NULL );  	}  	else  	{ @@ -6727,12 +6727,12 @@ void handle_debug_avatar_textures(void*)  void handle_grab_texture(void* data)  { -	LLVOAvatar::ETextureIndex index = (LLVOAvatar::ETextureIndex)((intptr_t)data); +	ETextureIndex index = (ETextureIndex)((intptr_t)data);  	LLVOAvatar* avatar = gAgent.getAvatarObject();  	if ( avatar )  	{  		const LLUUID& asset_id = avatar->grabLocalTexture(index); -		llinfos << "Adding baked texture " << asset_id << " to inventory." << llendl; +		LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << llendl;  		LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE;  		LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE;  		LLUUID folder_id(gInventory.findCategoryUUIDForType(asset_type)); @@ -6741,21 +6741,24 @@ void handle_grab_texture(void* data)  			std::string name = "Baked ";  			switch (index)  			{ -			case LLVOAvatar::TEX_EYES_BAKED: +			case TEX_EYES_BAKED:  				name.append("Iris");  				break; -			case LLVOAvatar::TEX_HEAD_BAKED: +			case TEX_HEAD_BAKED:  				name.append("Head");  				break; -			case LLVOAvatar::TEX_UPPER_BAKED: +			case TEX_UPPER_BAKED:  				name.append("Upper Body");  				break; -			case LLVOAvatar::TEX_LOWER_BAKED: +			case TEX_LOWER_BAKED:  				name.append("Lower Body");  				break; -			case LLVOAvatar::TEX_SKIRT_BAKED: +			case TEX_SKIRT_BAKED:  				name.append("Skirt");  				break; +			case TEX_HAIR_BAKED: +				name.append("Hair"); +				break;  			default:  				name.append("Unknown");  				break; @@ -6817,7 +6820,7 @@ void handle_grab_texture(void* data)  BOOL enable_grab_texture(void* data)  { -	LLVOAvatar::ETextureIndex index = (LLVOAvatar::ETextureIndex)((intptr_t)data); +	ETextureIndex index = (ETextureIndex)((intptr_t)data);  	LLVOAvatar* avatar = gAgent.getAvatarObject();  	if ( avatar )  	{ diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c840557f01..77b69d0ad4 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3671,7 +3671,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)  	avatarp->mSignaledAnimations.clear(); -	if (avatarp->mIsSelf) +	if (avatarp->isSelf())  	{  		LLUUID object_id; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e4ddbd42dd..4a81c06efb 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1889,7 +1889,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	if ( gShowObjectUpdates )  	{ -		if (!((mPrimitiveCode == LL_PCODE_LEGACY_AVATAR) && (((LLVOAvatar *) this)->mIsSelf)) +		if (!((mPrimitiveCode == LL_PCODE_LEGACY_AVATAR) && (((LLVOAvatar *) this)->isSelf()))  			&& mRegionp)  		{  			LLViewerObject* object = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, mRegionp); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 50fe66ea5e..e822c81500 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1420,6 +1420,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("SendUserReportWithScreenshot");  	capabilityNames.append("ServerReleaseNotes");  	capabilityNames.append("StartGroupProposal"); +	capabilityNames.append("UntrustedSimulatorMessage");  	capabilityNames.append("UpdateAgentLanguage");  	capabilityNames.append("UpdateGestureAgentInventory");  	capabilityNames.append("UpdateNotecardAgentInventory"); @@ -1427,8 +1428,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("UpdateGestureTaskInventory");  	capabilityNames.append("UpdateNotecardTaskInventory");  	capabilityNames.append("UpdateScriptTask"); +	capabilityNames.append("UploadBakedTexture");  	capabilityNames.append("ViewerStartAuction"); -	capabilityNames.append("UntrustedSimulatorMessage");  	capabilityNames.append("ViewerStats");  	// Please add new capabilities alphabetically to reduce  	// merge conflicts. diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3757923e27..8d20e4e91c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -32,175 +32,112 @@  #include "llviewerprecompiledheaders.h" -#include <algorithm> -#include <vector> -#include "llstl.h" -  #include "llvoavatar.h" -#include "llrender.h" +#include <stdio.h> +#include <ctype.h> +  #include "audioengine.h" -#include "imageids.h" -#include "indra_constants.h" -#include "llchat.h" -#include "llfontgl.h" -#include "llprimitive.h" -#include "lltextureentry.h" -#include "message.h"  #include "noise.h" -#include "sound_ids.h" -#include "lltimer.h" -#include "timing.h" -#include "llagent.h"			//  Get state values from here +#include "llagent.h" //  Get state values from here  #include "llviewercontrol.h" -#include "llcriticaldamp.h" -#include "lldir.h" -#include "lldrawable.h"  #include "lldrawpoolavatar.h" -#include "lldrawpoolalpha.h" -#include "lldrawpoolbump.h"  #include "lldriverparam.h"  #include "lleditingmotion.h"  #include "llemote.h" -#include "llface.h" -#include "llfasttimer.h"  #include "llfirstuse.h" -#include "llfloatercustomize.h" -#include "llfloatertools.h" -#include "llgldbg.h" -#include "llhandmotion.h"  #include "llheadrotmotion.h" -#include "llhudeffectbeam.h" -#include "llhudeffectlookat.h"  #include "llhudeffecttrail.h"  #include "llhudmanager.h" -#include "llhudtext.h" -#include "llinventorymodel.h"  #include "llinventoryview.h"  #include "llkeyframefallmotion.h" -#include "llkeyframemotion.h" -#include "llkeyframemotionparam.h"  #include "llkeyframestandmotion.h"  #include "llkeyframewalkmotion.h" -#include "llmenugl.h"  #include "llmutelist.h" -#include "llnetmap.h" -#include "llnotify.h" -#include "llquantize.h" -#include "llregionhandle.h" -#include "llresmgr.h"  #include "llselectmgr.h" -#include "llsky.h"  #include "llsprite.h" -#include "llstatusbar.h"  #include "lltargetingmotion.h"  #include "lltexlayer.h" -#include "lltoolgrab.h"		// for needsRenderBeam -#include "lltoolmgr.h"		// for needsRenderBeam +#include "lltoolgrab.h"	// for needsRenderBeam +#include "lltoolmgr.h" // for needsRenderBeam  #include "lltoolmorph.h"  #include "llviewercamera.h"  #include "llviewerimagelist.h" -#include "llviewerinventory.h"  #include "llviewermenu.h"  #include "llviewerobjectlist.h"  #include "llviewerparcelmgr.h" -#include "llviewerregion.h"  #include "llviewerstats.h" -#include "llviewerwindow.h" -#include "llvosky.h"  #include "llvovolume.h" -#include "llwearable.h" -#include "llwearablelist.h"  #include "llworld.h"  #include "pipeline.h" -#include "llspatialpartition.h"  #include "llviewershadermgr.h" -#include "llappviewer.h"  #include "llsky.h"  #include "llanimstatelabels.h" - -//#include "vtune/vtuneapi.h" -  #include "llgesturemgr.h" //needed to trigger the voice gesticulations -#include "llvoicevisualizer.h"   #include "llvoiceclient.h" +#include "llvoicevisualizer.h" // Ventrella -LLXmlTree LLVOAvatar::sXMLTree; -LLXmlTree LLVOAvatar::sSkeletonXMLTree; -LLVOAvatarSkeletonInfo* LLVOAvatar::sSkeletonInfo = NULL; -LLVOAvatarInfo* 		LLVOAvatar::sAvatarInfo = NULL; +#include "boost/lexical_cast.hpp" + +using namespace LLVOAvatarDefines; -BOOL gDebugAvatarRotation = FALSE; -S32 LLVOAvatar::sFreezeCounter = 0 ; +//----------------------------------------------------------------------------- +// Global constants +//----------------------------------------------------------------------------- +const LLUUID ANIM_AGENT_BODY_NOISE = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise" +const LLUUID ANIM_AGENT_BREATHE_ROT	= LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8");  //"breathe_rot" +const LLUUID ANIM_AGENT_EDITING	= LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb");  //"editing" +const LLUUID ANIM_AGENT_EYE	= LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea");  //"eye" +const LLUUID ANIM_AGENT_FLY_ADJUST = LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e");  //"fly_adjust" +const LLUUID ANIM_AGENT_HAND_MOTION	= LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578");  //"hand_motion" +const LLUUID ANIM_AGENT_HEAD_ROT = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d");  //"head_rot" +const LLUUID ANIM_AGENT_PELVIS_FIX = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b");  //"pelvis_fix" +const LLUUID ANIM_AGENT_TARGET = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55");  //"target" +const LLUUID ANIM_AGENT_WALK_ADJUST	= LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d");  //"walk_adjust" -//extern BOOL gVelocityInterpolate;  //-----------------------------------------------------------------------------  // Constants  //----------------------------------------------------------------------------- -const F32 MIN_PIXEL_AREA_FOR_COMPOSITE = 1024; +const std::string AVATAR_DEFAULT_CHAR = "avatar"; -F32 SHADOW_OFFSET_AMT = 0.03f; +const S32 MIN_PIXEL_AREA_FOR_COMPOSITE = 1024; +const F32 SHADOW_OFFSET_AMT = 0.03f; -#define DELTA_TIME_MIN			0.01f	// we clamp measured deltaTime to this -#define DELTA_TIME_MAX			0.2f	// range to insure stability of computations. +const F32 DELTA_TIME_MIN = 0.01f;	// we clamp measured deltaTime to this +const F32 DELTA_TIME_MAX = 0.2f;	// range to insure stability of computations.  const F32 PELVIS_LAG_FLYING		= 0.22f;// pelvis follow half life while flying -  const F32 PELVIS_LAG_WALKING	= 0.4f;	// ...while walking -  const F32 PELVIS_LAG_MOUSELOOK = 0.15f;  const F32 MOUSELOOK_PELVIS_FOLLOW_FACTOR = 0.5f; -  const F32 PELVIS_LAG_WHEN_FOLLOW_CAM_IS_ON = 0.0001f; // not zero! - something gets divided by this! -#define PELVIS_ROT_THRESHOLD_SLOW	60.0f	// amount of deviation allowed between -#define PELVIS_ROT_THRESHOLD_FAST	2.0f	// the pelvis and the view direction +const F32 PELVIS_ROT_THRESHOLD_SLOW = 60.0f;	// amount of deviation allowed between +const F32 PELVIS_ROT_THRESHOLD_FAST = 2.0f;	// the pelvis and the view direction  											// when moving fast & slow - -const F32 MIN_SPEED_PELVIS_FOLLOW = 0.1f; - -#define TORSO_NOISE_AMOUNT		1.f	// Amount of deviation from up-axis, in degrees -#define TORSO_NOISE_SPEED		0.2f	// Time scale factor on torso noise. +const F32 TORSO_NOISE_AMOUNT = 1.0f;	// Amount of deviation from up-axis, in degrees +const F32 TORSO_NOISE_SPEED = 0.2f;	// Time scale factor on torso noise.  const F32 BREATHE_ROT_MOTION_STRENGTH = 0.05f; -  const F32 BREATHE_SCALE_MOTION_STRENGTH = 0.005f; -#define PELVIS_NOISE_FACTOR		0.5f	// amount of random noise - -#define AUDIO_STEP_PRI			0xC0000000 -#define AUDIO_STEP_LO_SPEED		0.01f	// as average speed goes from lo to hi, -#define AUDIO_STEP_HI_SPEED		3.0f    // from lo to hi -#define AUDIO_STEP_LO_GAIN		0.15f	// the resulting gain will ramp linearly -#define AUDIO_STEP_HI_GAIN		0.15f - -const F32 DAMPED_MOTION_TIME_SCALE = 0.15f; - -const F32 LOOKAT_CAMERA_DIST_SQUARED = 25.f; - -#define AVATAR_HEADER		"Linden Avatar 1.0" -#define AVATAR_SECTION		"[avatar]" - -#define AVATAR_DEFAULT_CHAR	"avatar" -  const F32 MIN_SHADOW_HEIGHT = 0.f;  const F32 MAX_SHADOW_HEIGHT = 0.3f; -#define MIN_REQUIRED_PIXEL_AREA_BODY_NOISE (10000.f) -#define MIN_REQUIRED_PIXEL_AREA_BREATHE (10000.f) -#define MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX (40.f) +const S32 MIN_REQUIRED_PIXEL_AREA_BODY_NOISE = 10000; +const S32 MIN_REQUIRED_PIXEL_AREA_BREATHE = 10000; +const S32 MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX = 40; -const S32 LOCTEX_IMAGE_SIZE_SELF = 512; -const S32 LOCTEX_IMAGE_AREA_SELF = LOCTEX_IMAGE_SIZE_SELF * LOCTEX_IMAGE_SIZE_SELF; -const S32 LOCTEX_IMAGE_SIZE_OTHER = LOCTEX_IMAGE_SIZE_SELF / 4;  // The size of local textures for other (!mIsSelf) avatars -const S32 LOCTEX_IMAGE_AREA_OTHER = LOCTEX_IMAGE_SIZE_OTHER * LOCTEX_IMAGE_SIZE_OTHER; +const S32 TEX_IMAGE_SIZE_SELF = 512; +const S32 TEX_IMAGE_AREA_SELF = TEX_IMAGE_SIZE_SELF * TEX_IMAGE_SIZE_SELF; +const S32 TEX_IMAGE_SIZE_OTHER = TEX_IMAGE_SIZE_SELF / 4;  // The size of local textures for other (!mIsSelf) avatars +const S32 TEX_IMAGE_AREA_OTHER = TEX_IMAGE_SIZE_OTHER * TEX_IMAGE_SIZE_OTHER;  const F32 HEAD_MOVEMENT_AVG_TIME = 0.9f;  const S32 MORPH_MASK_REQUESTED_DISCARD = 0; -const S32 MIN_PIXEL_AREA_BUMP = 500;  // Discard level at which to switch to baked textures  // Should probably be 4 or 3, but didn't want to change it while change other logic - SJB @@ -210,95 +147,34 @@ const F32 FOOT_COLLIDE_FUDGE = 0.04f;  const F32 HOVER_EFFECT_MAX_SPEED = 3.f;  const F32 HOVER_EFFECT_STRENGTH = 0.f; -F32 UNDERWATER_EFFECT_STRENGTH = 0.1f; +const F32 UNDERWATER_EFFECT_STRENGTH = 0.1f;  const F32 UNDERWATER_FREQUENCY_DAMP = 0.33f;  const F32 APPEARANCE_MORPH_TIME = 0.65f; -const F32 CAMERA_SHAKE_ACCEL_THRESHOLD_SQUARED = 5.f * 5.f;  const F32 TIME_BEFORE_MESH_CLEANUP = 5.f; // seconds  const S32 AVATAR_RELEASE_THRESHOLD = 10; // number of avatar instances before releasing memory  const F32 FOOT_GROUND_COLLISION_TOLERANCE = 0.25f;  const F32 AVATAR_LOD_TWEAK_RANGE = 0.7f; -const S32 MAX_LOD_CHANGES_PER_FRAME = 2;  const S32 MAX_BUBBLE_CHAT_LENGTH = 1023;  const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;  const F32 CHAT_FADE_TIME = 8.0;  const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f; -const S32 MAX_BUBBLES = 7; -S32 LLVOAvatar::sMaxVisible = 50; - -LLVOAvatar::ETextureIndex LLVOAvatar::sBakedTextureIndices[BAKED_TEXTURE_COUNT] =  +enum ERenderName  { -	LLVOAvatar::TEX_HEAD_BAKED, -	LLVOAvatar::TEX_UPPER_BAKED, -	LLVOAvatar::TEX_LOWER_BAKED, -	LLVOAvatar::TEX_EYES_BAKED, -	LLVOAvatar::TEX_SKIRT_BAKED +	RENDER_NAME_NEVER, +	RENDER_NAME_FADE, +	RENDER_NAME_ALWAYS  };  //----------------------------------------------------------------------------- -// Utility functions -//----------------------------------------------------------------------------- - -static F32 calc_bouncy_animation(F32 x) -{ -	return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f; -} - -BOOL LLLineSegmentCapsuleIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& p1, const LLVector3& p2, const F32& radius, LLVector3& result) -{ -	return FALSE; -} - -//----------------------------------------------------------------------------- -// Static Data +// Callback data  //----------------------------------------------------------------------------- -S32 LLVOAvatar::sMaxOtherAvatarsToComposite = 1;  // Only this many avatars (other than yourself) can be composited at a time.  Set in initClass(). -LLMap< LLGLenum, LLGLuint*> LLVOAvatar::sScratchTexNames; -LLMap< LLGLenum, F32*> LLVOAvatar::sScratchTexLastBindTime; -S32 LLVOAvatar::sScratchTexBytes = 0; -F32 LLVOAvatar::sRenderDistance = 256.f; -S32	LLVOAvatar::sNumVisibleAvatars = 0; -S32	LLVOAvatar::sNumLODChangesThisFrame = 0; - -LLUUID LLVOAvatar::sStepSoundOnLand = LLUUID("e8af4a28-aa83-4310-a7c4-c047e15ea0df"); -LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] = -{ -	LLUUID(SND_STONE_RUBBER), -	LLUUID(SND_METAL_RUBBER), -	LLUUID(SND_GLASS_RUBBER), -	LLUUID(SND_WOOD_RUBBER), -	LLUUID(SND_FLESH_RUBBER), -	LLUUID(SND_RUBBER_PLASTIC), -	LLUUID(SND_RUBBER_RUBBER) -}; - -// static -S32 LLVOAvatar::sRenderName = RENDER_NAME_ALWAYS; -BOOL LLVOAvatar::sRenderGroupTitles = TRUE; -S32 LLVOAvatar::sNumVisibleChatBubbles = 0; -BOOL LLVOAvatar::sDebugInvisible = FALSE; -BOOL LLVOAvatar::sShowAttachmentPoints = FALSE; -BOOL LLVOAvatar::sShowAnimationDebug = FALSE; -BOOL LLVOAvatar::sShowFootPlane = FALSE; -BOOL LLVOAvatar::sShowCollisionVolumes = FALSE; -BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; -F32 LLVOAvatar::sLODFactor = 1.f; -BOOL LLVOAvatar::sUseImpostors = FALSE; -BOOL LLVOAvatar::sJointDebug = FALSE; -S32 LLVOAvatar::sCurJoint = 0; -S32 LLVOAvatar::sCurVolume = 0; -F32 LLVOAvatar::sUnbakedTime = 0.f; -F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; -F32 LLVOAvatar::sGreyTime = 0.f; -F32 LLVOAvatar::sGreyUpdateTime = 0.f; -  struct LLAvatarTexData  { -	LLAvatarTexData( const LLUUID& id, LLVOAvatar::ELocTexIndex index ) +	LLAvatarTexData( const LLUUID& id, ETextureIndex index )  		: mAvatarID(id), mIndex(index) {}  	LLUUID				mAvatarID; -	LLVOAvatar::ELocTexIndex	mIndex; +	ETextureIndex	mIndex;  };  struct LLTextureMaskData @@ -309,6 +185,142 @@ struct LLTextureMaskData  	S32					mLastDiscardLevel;  }; +/********************************************************************************* + **                                                                             ** + ** Begin LLVOAvatar Support classes + ** + **/ + +//------------------------------------------------------------------------ +// LLVOBoneInfo +// Trans/Scale/Rot etc. info about each avatar bone.  Used by LLVOAvatarSkeleton. +//------------------------------------------------------------------------ +class LLVOAvatarBoneInfo +{ +	friend class LLVOAvatar; +	friend class LLVOAvatarSkeletonInfo; +public: +	LLVOAvatarBoneInfo() : mIsJoint(FALSE) {} +	~LLVOAvatarBoneInfo() +	{ +		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer()); +	} +	BOOL parseXml(LLXmlTreeNode* node); +	 +private: +	std::string mName; +	BOOL mIsJoint; +	LLVector3 mPos; +	LLVector3 mRot; +	LLVector3 mScale; +	LLVector3 mPivot; +	typedef std::vector<LLVOAvatarBoneInfo*> child_list_t; +	child_list_t mChildList; +}; + +//------------------------------------------------------------------------ +// LLVOAvatarSkeletonInfo +// Overall avatar skeleton +//------------------------------------------------------------------------ +class LLVOAvatarSkeletonInfo +{ +	friend class LLVOAvatar; +public: +	LLVOAvatarSkeletonInfo() : +		mNumBones(0), mNumCollisionVolumes(0) {} +	~LLVOAvatarSkeletonInfo() +	{ +		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer()); +	} +	BOOL parseXml(LLXmlTreeNode* node); +	S32 getNumBones() const { return mNumBones; } +	S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; } +	 +private: +	S32 mNumBones; +	S32 mNumCollisionVolumes; +	typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t; +	bone_info_list_t mBoneInfoList; +}; + + +//------------------------------------------------------------------------ +// LLVOAvatarXmlInfo +// One instance (in LLVOAvatar) with common data parsed from the XML files +//------------------------------------------------------------------------ +class LLVOAvatarXmlInfo +{ +	friend class LLVOAvatar; +public: +	LLVOAvatarXmlInfo(); +	~LLVOAvatarXmlInfo(); +	 +private: +	BOOL 	parseXmlSkeletonNode(LLXmlTreeNode* root); +	BOOL 	parseXmlMeshNodes(LLXmlTreeNode* root); +	BOOL 	parseXmlColorNodes(LLXmlTreeNode* root); +	BOOL 	parseXmlLayerNodes(LLXmlTreeNode* root); +	BOOL 	parseXmlDriverNodes(LLXmlTreeNode* root); +	 +	struct LLVOAvatarMeshInfo +	{ +		typedef std::pair<LLPolyMorphTargetInfo*,BOOL> morph_info_pair_t; +		typedef std::vector<morph_info_pair_t> morph_info_list_t; + +		LLVOAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {} +		~LLVOAvatarMeshInfo() +		{ +			morph_info_list_t::iterator iter; +			for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++) +			{ +				delete iter->first; +			} +			mPolyMorphTargetInfoList.clear(); +		} + +		std::string mType; +		S32			mLOD; +		std::string	mMeshFileName; +		std::string	mReferenceMeshName; +		F32			mMinPixelArea; +		morph_info_list_t mPolyMorphTargetInfoList; +	}; +	typedef std::vector<LLVOAvatarMeshInfo*> mesh_info_list_t; +	mesh_info_list_t mMeshInfoList; + +	typedef std::vector<LLPolySkeletalDistortionInfo*> skeletal_distortion_info_list_t; +	skeletal_distortion_info_list_t mSkeletalDistortionInfoList; +	 +	struct LLVOAvatarAttachmentInfo +	{ +		LLVOAvatarAttachmentInfo() +			: mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE), +			  mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {} +		std::string mName; +		std::string mJointName; +		LLVector3 mPosition; +		LLVector3 mRotationEuler; +		S32 mGroup; +		S32 mAttachmentID; +		S32 mPieMenuSlice; +		BOOL mVisibleFirstPerson; +		BOOL mIsHUDAttachment; +		BOOL mHasPosition; +		BOOL mHasRotation; +	}; +	typedef std::vector<LLVOAvatarAttachmentInfo*> attachment_info_list_t; +	attachment_info_list_t mAttachmentInfoList; +	 +	LLTexGlobalColorInfo *mTexSkinColorInfo; +	LLTexGlobalColorInfo *mTexHairColorInfo; +	LLTexGlobalColorInfo *mTexEyeColorInfo; + +	typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t; +	layer_info_list_t mLayerInfoList; + +	typedef std::vector<LLDriverParamInfo*> driver_info_list_t; +	driver_info_list_t mDriverInfoList; +};  //-----------------------------------------------------------------------------  // class LLBodyNoiseMotion @@ -322,7 +334,6 @@ public:  		: LLMotion(id)  	{  		mName = "body_noise"; -  		mTorsoState = new LLJointState;  	} @@ -409,7 +420,7 @@ public:  	// called when a motion is deactivated  	virtual void onDeactivate() {} -public: +private:  	//-------------------------------------------------------------------------  	// joint states to be animated  	//------------------------------------------------------------------------- @@ -430,12 +441,11 @@ public:  		mCharacter(NULL)  	{  		mName = "breathe_rot"; -  		mChestState = new LLJointState;  	}  	// Destructor -	virtual ~LLBreatheMotionRot() { } +	virtual ~LLBreatheMotionRot() {}  public:  	//------------------------------------------------------------------------- @@ -518,7 +528,7 @@ public:  	// called when a motion is deactivated  	virtual void onDeactivate() {} -public: +private:  	//-------------------------------------------------------------------------  	// joint states to be animated  	//------------------------------------------------------------------------- @@ -615,7 +625,7 @@ public:  	// called when a motion is deactivated  	virtual void onDeactivate() {} -public: +private:  	//-------------------------------------------------------------------------  	// joint states to be animated  	//------------------------------------------------------------------------- @@ -623,20 +633,74 @@ public:  	LLCharacter*		mCharacter;  }; +/** + ** + ** End LLVOAvatar Support classes + **                                                                             ** + *********************************************************************************/ + + +//----------------------------------------------------------------------------- +// Static Data +//----------------------------------------------------------------------------- +LLXmlTree LLVOAvatar::sXMLTree; +LLXmlTree LLVOAvatar::sSkeletonXMLTree; +BOOL LLVOAvatar::sDebugAvatarRotation = FALSE; +LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL; +LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL; +LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL; +S32 LLVOAvatar::sFreezeCounter = 0; +S32 LLVOAvatar::sMaxVisible = 50; +LLMap< LLGLenum, LLGLuint*> LLVOAvatar::sScratchTexNames; +LLMap< LLGLenum, F32*> LLVOAvatar::sScratchTexLastBindTime; +S32 LLVOAvatar::sScratchTexBytes = 0; +F32 LLVOAvatar::sRenderDistance = 256.f; +S32	LLVOAvatar::sNumVisibleAvatars = 0; +S32	LLVOAvatar::sNumLODChangesThisFrame = 0; + +const LLUUID LLVOAvatar::sStepSoundOnLand = LLUUID("e8af4a28-aa83-4310-a7c4-c047e15ea0df"); +const LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] = +{ +	LLUUID(SND_STONE_RUBBER), +	LLUUID(SND_METAL_RUBBER), +	LLUUID(SND_GLASS_RUBBER), +	LLUUID(SND_WOOD_RUBBER), +	LLUUID(SND_FLESH_RUBBER), +	LLUUID(SND_RUBBER_PLASTIC), +	LLUUID(SND_RUBBER_RUBBER) +}; + +S32 LLVOAvatar::sRenderName = RENDER_NAME_ALWAYS; +BOOL LLVOAvatar::sRenderGroupTitles = TRUE; +S32 LLVOAvatar::sNumVisibleChatBubbles = 0; +BOOL LLVOAvatar::sDebugInvisible = FALSE; +BOOL LLVOAvatar::sShowAttachmentPoints = FALSE; +BOOL LLVOAvatar::sShowAnimationDebug = FALSE; +BOOL LLVOAvatar::sShowFootPlane = FALSE; +BOOL LLVOAvatar::sShowCollisionVolumes = FALSE; +BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; +F32 LLVOAvatar::sLODFactor = 1.f; +BOOL LLVOAvatar::sUseImpostors = FALSE; +BOOL LLVOAvatar::sJointDebug = FALSE; + +F32 LLVOAvatar::sUnbakedTime = 0.f; +F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; +F32 LLVOAvatar::sGreyTime = 0.f; +F32 LLVOAvatar::sGreyUpdateTime = 0.f; + +//----------------------------------------------------------------------------- +// Helper functions +//----------------------------------------------------------------------------- +static F32 calc_bouncy_animation(F32 x); +static U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures); +  //-----------------------------------------------------------------------------  // LLVOAvatar()  //----------------------------------------------------------------------------- -LLVOAvatar::LLVOAvatar( -	const LLUUID& id, -	const LLPCode pcode, -	LLViewerRegion* regionp) -	: +LLVOAvatar::LLVOAvatar(const LLUUID& id, +					   const LLPCode pcode, +					   LLViewerRegion* regionp) :  	LLViewerObject(id, pcode, regionp), -	mLastHeadBakedID( IMG_DEFAULT_AVATAR ), -	mLastUpperBodyBakedID( IMG_DEFAULT_AVATAR ), -	mLastLowerBodyBakedID( IMG_DEFAULT_AVATAR ), -	mLastEyesBakedID( IMG_DEFAULT_AVATAR ), -	mLastSkirtBakedID( IMG_DEFAULT_AVATAR ),  	mIsDummy(FALSE),  	mSpecialRenderMode(0),  	mTurning(FALSE), @@ -654,12 +718,6 @@ LLVOAvatar::LLVOAvatar(  	mAppearanceAnimSetByUser(FALSE),  	mLastAppearanceBlendTime(0.f),  	mAppearanceAnimating(FALSE), -	mHeadLayerSet( NULL ), -	mUpperBodyLayerSet( NULL ), -	mLowerBodyLayerSet( NULL ), -	mEyesLayerSet( NULL ), -	mSkirtLayerSet( NULL ), -	mRenderPriority(1.0f),  	mNameString(),  	mTitle(),  	mNameAway(FALSE), @@ -671,17 +729,6 @@ LLVOAvatar::LLVOAvatar(  	mRegionCrossingCount(0),  	mFirstTEMessageReceived( FALSE ),  	mFirstAppearanceMessageReceived( FALSE ), -	mHeadBakedLoaded(FALSE), -	mHeadMaskDiscard(-1), -	mUpperBakedLoaded(FALSE), -	mUpperMaskDiscard(-1), -	mLowerBakedLoaded(FALSE), -	mLowerMaskDiscard(-1), -	mEyesBakedLoaded(FALSE), -	mSkirtBakedLoaded(FALSE), -	mHeadMaskTexName(0), -	mUpperMaskTexName(0), -	mLowerMaskTexName(0),  	mCulled( FALSE ),  	mVisibilityRank(0),  	mTexSkinColor( NULL ), @@ -689,24 +736,36 @@ LLVOAvatar::LLVOAvatar(  	mTexEyeColor( NULL ),  	mNeedsSkin(FALSE),  	mUpdatePeriod(1), -	mFullyLoadedInitialized(FALSE) +	mFullyLoadedInitialized(FALSE), +	mHasBakedHair( FALSE )  {  	LLMemType mt(LLMemType::MTYPE_AVATAR); -	  	//VTResume();  // VTune  	// mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline -	bool needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job +	const bool needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job  	mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );  	lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl;  	mPelvisp = NULL; -	for( S32 i=0; i<LOCTEX_NUM_ENTRIES; i++ ) +	for( S32 i=0; i<TEX_NUM_INDICES; i++ ) +	{ +		if (isIndexLocalTexture((ETextureIndex)i)) +		{ +			mLocalTextureData[(ETextureIndex)i] = LocalTextureData(); +		} +	} + +	mBakedTextureData.resize(BAKED_NUM_INDICES); +	for (U32 i = 0; i < mBakedTextureData.size(); i++ )  	{ -		mLocalTextureBaked[i] = FALSE; -		mLocalTextureDiscard[i] = MAX_DISCARD_LEVEL+1; +		mBakedTextureData[i].mLastTextureIndex = IMG_DEFAULT_AVATAR; +		mBakedTextureData[i].mTexLayerSet = NULL; +		mBakedTextureData[i].mIsLoaded = false; +		mBakedTextureData[i].mMaskTexName = 0; +		mBakedTextureData[i].mTextureIndex = getTextureIndex((EBakedTextureIndex)i);  	}  	mDirtyMesh = TRUE;	// Dirty geometry, need to regenerate. @@ -744,7 +803,7 @@ LLVOAvatar::LLVOAvatar(  	mImpostorDistance = 0;  	mImpostorPixelArea = 0; -	setNumTEs(TEX_NUM_ENTRIES); +	setNumTEs(TEX_NUM_INDICES);  	mbCanSelect = TRUE; @@ -777,118 +836,71 @@ LLVOAvatar::LLVOAvatar(  	//-------------------------------------------------------------------------  	mRoot.setName( "mRoot" ); -	// skinned mesh objects -	mHairLOD.setName("mHairLOD"); -	mHairMesh0.setName("mHairMesh0"); -	mHairMesh0.setMeshID(MESH_ID_HAIR); -	mHairMesh1.setName("mHairMesh1"); -	mHairMesh2.setName("mHairMesh2"); -	mHairMesh3.setName("mHairMesh3"); -	mHairMesh4.setName("mHairMesh4"); -	mHairMesh5.setName("mHairMesh5"); -	 -	mHairMesh0.setIsTransparent(TRUE); -	mHairMesh1.setIsTransparent(TRUE); -	mHairMesh2.setIsTransparent(TRUE); -	mHairMesh3.setIsTransparent(TRUE); -	mHairMesh4.setIsTransparent(TRUE); -	mHairMesh5.setIsTransparent(TRUE); - -	mHeadLOD.setName("mHeadLOD"); -	mHeadMesh0.setName("mHeadMesh0"); -	mHeadMesh0.setMeshID(MESH_ID_HEAD); -	mHeadMesh1.setName("mHeadMesh1"); -	mHeadMesh2.setName("mHeadMesh2"); -	mHeadMesh3.setName("mHeadMesh3"); -	mHeadMesh4.setName("mHeadMesh4"); -	 -	mEyeLashLOD.setName("mEyeLashLOD"); -	mEyeLashMesh0.setName("mEyeLashMesh0"); -	mEyeLashMesh0.setMeshID(MESH_ID_HEAD); -	mEyeLashMesh0.setIsTransparent(TRUE); - -	mUpperBodyLOD.setName("mUpperBodyLOD"); -	mUpperBodyMesh0.setName("mUpperBodyMesh0"); -	mUpperBodyMesh0.setMeshID(MESH_ID_UPPER_BODY); -	mUpperBodyMesh1.setName("mUpperBodyMesh1"); -	mUpperBodyMesh2.setName("mUpperBodyMesh2"); -	mUpperBodyMesh3.setName("mUpperBodyMesh3"); -	mUpperBodyMesh4.setName("mUpperBodyMesh4"); - -	mLowerBodyLOD.setName("mLowerBodyLOD"); -	mLowerBodyMesh0.setName("mLowerBodyMesh0"); -	mLowerBodyMesh0.setMeshID(MESH_ID_LOWER_BODY); -	mLowerBodyMesh1.setName("mLowerBodyMesh1"); -	mLowerBodyMesh2.setName("mLowerBodyMesh2"); -	mLowerBodyMesh3.setName("mLowerBodyMesh3"); -	mLowerBodyMesh4.setName("mLowerBodyMesh4"); - -	mEyeBallLeftLOD.setName("mEyeBallLeftLOD"); -	mEyeBallLeftMesh0.setName("mEyeBallLeftMesh0"); -	mEyeBallLeftMesh1.setName("mEyeBallLeftMesh1"); - -	mEyeBallRightLOD.setName("mEyeBallRightLOD"); -	mEyeBallRightMesh0.setName("mEyeBallRightMesh0"); -	mEyeBallRightMesh1.setName("mEyeBallRightMesh1"); - -	mSkirtLOD.setName("mSkirtLOD"); -	mSkirtMesh0.setName("mSkirtMesh0"); -	mSkirtMesh0.setMeshID(MESH_ID_SKIRT); -	mSkirtMesh1.setName("mSkirtMesh1"); -	mSkirtMesh2.setName("mSkirtMesh2"); -	mSkirtMesh3.setName("mSkirtMesh3"); -	mSkirtMesh4.setName("mSkirtMesh4"); - -	mSkirtMesh0.setIsTransparent(TRUE); -	mSkirtMesh1.setIsTransparent(TRUE); -	mSkirtMesh2.setIsTransparent(TRUE); -	mSkirtMesh3.setIsTransparent(TRUE); -	mSkirtMesh4.setIsTransparent(TRUE); - -	// set the pick names for the avatar -	mHeadMesh0.setPickName( LLViewerJoint::PN_0 ); -	mHeadMesh1.setPickName( LLViewerJoint::PN_0 ); -	mHeadMesh2.setPickName( LLViewerJoint::PN_0 ); -	mHeadMesh3.setPickName( LLViewerJoint::PN_0 ); -	mHeadMesh4.setPickName( LLViewerJoint::PN_0 ); -	mEyeLashMesh0.setPickName( LLViewerJoint::PN_0 ); - -	mUpperBodyMesh0.setPickName( LLViewerJoint::PN_1 ); -	mUpperBodyMesh1.setPickName( LLViewerJoint::PN_1 ); -	mUpperBodyMesh2.setPickName( LLViewerJoint::PN_1 ); -	mUpperBodyMesh3.setPickName( LLViewerJoint::PN_1 ); -	mUpperBodyMesh4.setPickName( LLViewerJoint::PN_1 ); - -	mLowerBodyMesh0.setPickName( LLViewerJoint::PN_2 ); -	mLowerBodyMesh1.setPickName( LLViewerJoint::PN_2 ); -	mLowerBodyMesh2.setPickName( LLViewerJoint::PN_2 ); -	mLowerBodyMesh3.setPickName( LLViewerJoint::PN_2 ); -	mLowerBodyMesh4.setPickName( LLViewerJoint::PN_2 ); - -	mEyeBallLeftMesh0.setPickName( LLViewerJoint::PN_3 ); -	mEyeBallLeftMesh1.setPickName( LLViewerJoint::PN_3 ); -	mEyeBallRightMesh0.setPickName( LLViewerJoint::PN_3 ); -	mEyeBallRightMesh1.setPickName( LLViewerJoint::PN_3 ); - -	mHairMesh0.setPickName( LLViewerJoint::PN_4); -	mHairMesh1.setPickName( LLViewerJoint::PN_4); -	mHairMesh2.setPickName( LLViewerJoint::PN_4); -	mHairMesh3.setPickName( LLViewerJoint::PN_4); -	mHairMesh4.setPickName( LLViewerJoint::PN_4); -	mHairMesh5.setPickName( LLViewerJoint::PN_4); - -	mSkirtMesh0.setPickName( LLViewerJoint::PN_5 ); -	mSkirtMesh1.setPickName( LLViewerJoint::PN_5 ); -	mSkirtMesh2.setPickName( LLViewerJoint::PN_5 ); -	mSkirtMesh3.setPickName( LLViewerJoint::PN_5 ); -	mSkirtMesh4.setPickName( LLViewerJoint::PN_5 ); - -	// material settings - -	mEyeBallLeftMesh0.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); -	mEyeBallLeftMesh1.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); -	mEyeBallRightMesh0.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); -	mEyeBallRightMesh1.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); +	for (LLVOAvatarDictionary::mesh_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin(); +		 iter != LLVOAvatarDictionary::getInstance()->getMeshes().end(); +		 iter++) +	{ +		const EMeshIndex mesh_index = iter->first; +		const LLVOAvatarDictionary::MeshDictionaryEntry *mesh_dict = iter->second; + +		LLViewerJoint* joint = new LLViewerJoint(); +		joint->setName(mesh_dict->mName); +		joint->setMeshID(mesh_index); +		mMeshLOD.push_back(joint); +		 +		/* mHairLOD.setName("mHairLOD"); +		   mHairMesh0.setName("mHairMesh0"); +		   mHairMesh0.setMeshID(MESH_ID_HAIR); +		   mHairMesh1.setName("mHairMesh1"); */ +		for (U32 lod = 0; lod < mesh_dict->mLOD; lod++) +		{ +			LLViewerJointMesh* mesh = new LLViewerJointMesh(); +			std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod); +			// We pre-pended an m - need to capitalize first character for camelCase +			mesh_name[1] = toupper(mesh_name[1]); +			mesh->setName(mesh_name); +			mesh->setMeshID(mesh_index); +			mesh->setPickName(mesh_dict->mPickName); +			switch((int)mesh_index) +			{ +				case MESH_ID_HAIR: +					mesh->setIsTransparent(TRUE); +					break; +				case MESH_ID_SKIRT: +					mesh->setIsTransparent(TRUE); +					break; +				case MESH_ID_EYEBALL_LEFT: +				case MESH_ID_EYEBALL_RIGHT: +					mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); +					break; +			} + +			joint->mMeshParts.push_back(mesh); +		} +	} + +	//------------------------------------------------------------------------- +	// associate baked textures with meshes +	//------------------------------------------------------------------------- +	for (LLVOAvatarDictionary::mesh_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin(); +		 iter != LLVOAvatarDictionary::getInstance()->getMeshes().end(); +		 iter++) +	{ +		const EMeshIndex mesh_index = iter->first; +		const LLVOAvatarDictionary::MeshDictionaryEntry *mesh_dict = iter->second; +		const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID; + +		// Skip it if there's no associated baked texture. +		if (baked_texture_index == BAKED_NUM_INDICES) continue; + +		for (std::vector<LLViewerJointMesh* >::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin(); +			 iter != mMeshLOD[mesh_index]->mMeshParts.end(); iter++) +		{ +			LLViewerJointMesh* mesh = (LLViewerJointMesh*) *iter; +			mBakedTextureData[(int)baked_texture_index].mMeshes.push_back(mesh); +		} +	} +  	//-------------------------------------------------------------------------  	// register motions @@ -987,20 +999,11 @@ LLVOAvatar::~LLVOAvatar()  	mNumJoints = 0; -	delete mHeadLayerSet; -	mHeadLayerSet = NULL; - -	delete mUpperBodyLayerSet; -	mUpperBodyLayerSet = NULL; - -	delete mLowerBodyLayerSet; -	mLowerBodyLayerSet = NULL; - -	delete mEyesLayerSet; -	mEyesLayerSet = NULL; - -	delete mSkirtLayerSet; -	mSkirtLayerSet = NULL; +	for (U32 i = 0; i < mBakedTextureData.size(); i++) +	{ +		delete mBakedTextureData[i].mTexLayerSet; +		mBakedTextureData[i].mTexLayerSet = NULL; +	}  	std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());  	mAttachmentPoints.clear(); @@ -1014,6 +1017,16 @@ LLVOAvatar::~LLVOAvatar()  	std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer());  	mMeshes.clear(); + +	for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin(); +		jointIter != mMeshLOD.end(); jointIter++) +	{ +		LLViewerJoint* joint = (LLViewerJoint *) *jointIter; +		std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer()); +		joint->mMeshParts.clear(); +	} +	std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer()); +	mMeshLOD.clear();  	mDead = TRUE; @@ -1045,45 +1058,34 @@ BOOL LLVOAvatar::isFullyBaked()  {  	if (mIsDummy) return TRUE;  	if (getNumTEs() == 0) return FALSE; -	 -	BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	if (isWearingWearableType(WT_SKIRT)) -	{ -		return head_baked && upper_baked && lower_baked && eyes_baked && skirt_baked; -	} -	else +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		return head_baked && upper_baked && lower_baked && eyes_baked; +		if (!isTextureDefined(mBakedTextureData[i].mTextureIndex) +			&& ( (i != BAKED_SKIRT) || isWearingWearableType(WT_SKIRT) ) ) +		{ +			return FALSE; +		}  	} +	return TRUE;  } -void LLVOAvatar::deleteLayerSetCaches() +void LLVOAvatar::deleteLayerSetCaches(bool clearAll)  { -	if( mHeadLayerSet )			mHeadLayerSet->deleteCaches(); -	if( mUpperBodyLayerSet )	mUpperBodyLayerSet->deleteCaches(); -	if( mLowerBodyLayerSet )	mLowerBodyLayerSet->deleteCaches(); -	if( mEyesLayerSet )			mEyesLayerSet->deleteCaches(); -	if( mSkirtLayerSet )		mSkirtLayerSet->deleteCaches(); - -	if(mUpperMaskTexName) -	{ -		glDeleteTextures(1, (GLuint*)&mUpperMaskTexName); -		mUpperMaskTexName = 0 ; -	} -	if(mHeadMaskTexName) -	{ -		glDeleteTextures(1, (GLuint*)&mHeadMaskTexName); -		mHeadMaskTexName = 0 ; -	} -	if(mLowerMaskTexName) +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		glDeleteTextures(1, (GLuint*)&mLowerMaskTexName); -		mLowerMaskTexName = 0 ; +		if (mBakedTextureData[i].mTexLayerSet) +		{ +			if ((i != BAKED_HAIR || mIsSelf) && !clearAll)		// Backwards compatibility - can be removed after hair baking is mandatory on the grid +			{ +				mBakedTextureData[i].mTexLayerSet->deleteCaches(); +			} +		} +		if (mBakedTextureData[i].mMaskTexName) +		{ +			glDeleteTextures(1, (GLuint*)&(mBakedTextureData[i].mMaskTexName)); +			mBakedTextureData[i].mMaskTexName = 0 ; +		}  	}  } @@ -1154,7 +1156,7 @@ void LLVOAvatar::dumpBakedStatus()  			llcont << " DEAD ("<< inst->getNumRefs() << " refs)";  		} -		if( inst->mIsSelf ) +		if( inst->isSelf() )  		{  			llcont << " (self)";  		} @@ -1181,130 +1183,26 @@ void LLVOAvatar::dumpBakedStatus()  		else  		{  			llcont << " Unbaked ("; -			if( inst->getTEImage( TEX_HEAD_BAKED )->getID()  == IMG_DEFAULT_AVATAR ) -			{ -				llcont << " head"; -			} - -			if( inst->getTEImage( TEX_UPPER_BAKED )->getID() == IMG_DEFAULT_AVATAR ) -			{ -				llcont << " upper"; -			} - -			if( inst->getTEImage( TEX_LOWER_BAKED )->getID() == IMG_DEFAULT_AVATAR ) -			{ -				llcont << " lower"; -			} - -			if( inst->getTEImage( TEX_EYES_BAKED )->getID()  == IMG_DEFAULT_AVATAR ) -			{ -				llcont << " eyes"; -			} - -			if (inst->isWearingWearableType(WT_SKIRT)) +			 +			for (LLVOAvatarDictionary::baked_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); +				 iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); +				 iter++)  			{ -				if( inst->getTEImage( TEX_SKIRT_BAKED )->getID()  == IMG_DEFAULT_AVATAR ) +				const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = iter->second; +				const ETextureIndex index = baked_dict->mTextureIndex; +				if (!inst->isTextureDefined(index))  				{ -					llcont << " skirt"; +					llcont << " " << LLVOAvatarDictionary::getInstance()->getTexture(index)->mName;  				}  			} -			llcont << " ) " << inst->getUnbakedPixelAreaRank() << "/" << LLVOAvatar::sMaxOtherAvatarsToComposite; +			llcont << " ) " << inst->getUnbakedPixelAreaRank();  			if( inst->isCulled() )  			{  				llcont << " culled";  			}  		}  		llcont << llendl; -/* -		if( inst->isDead() ) -		{ -			llinfos << "DEAD LIST " << llendl; - -			 -			for( S32 i = 0; i < inst->mOwners.count(); i++ ) -			{ -				llinfos << i << llendl; -				LLPointer<LLViewerObject>* owner = (LLPointer<LLViewerObject>*)(inst->mOwners[i]); -				LLPointer<LLViewerObject>* cur; -				if( !owner->mName.isEmpty() ) -				{ -					llinfos << "    " << owner->mName << llendl; -				} - -				LLViewerObject* key_vo; -				for( key_vo = gObjectList.mActiveObjects.getFirstKey(); key_vo; key_vo = gObjectList.mActiveObjects.getNextKey() ) -				{ -					cur = &(gObjectList.mActiveObjects.getCurrentDataWithoutIncrement()); -					if( cur == owner ) -					{ -						llinfos << "    gObjectList.mActiveObjects" << llendl; -					} -				} - -				for( key_vo = gObjectList.mAvatarObjects.getFirstKey(); key_vo; key_vo = gObjectList.mAvatarObjects.getNextKey() ) -				{ -					cur = &(gObjectList.mAvatarObjects.getCurrentDataWithoutIncrement());	 -					if( cur == owner ) -					{ -						llinfos << "    gObjectList.mAvatarObjects" << llendl; -					} -				} - -				LLUUID id; -				for( id = gObjectList.mDeadObjects.getFirstKey(); id; id = gObjectList.mDeadObjects.getNextKey() ) -				{ -					cur = &(gObjectList.mDeadObjects.getCurrentDataWithoutIncrement()); -					if( cur == owner ) -					{ -						llinfos << "    gObjectList.mDeadObjects" << llendl; -					} -				} - - -				for( id = gObjectList.mUUIDObjectMap.getFirstKey(); id; id = gObjectList.mUUIDObjectMap.getNextKey() ) -				{ -					cur = &(gObjectList.mUUIDObjectMap.getCurrentDataWithoutIncrement()); -					if( cur == owner ) -					{ -						llinfos << "    gObjectList.mUUIDObjectMap" << llendl; -					} -				} - -				S32 j; -				S32 k; -				for( j = 0; j < 16; j++ ) -				{ -					for( k = 0; k < 10; k++ ) -					{ -						cur = &(gObjectList.mCloseObjects[j][k]); -						if( cur == owner ) -						{ -							llinfos << "    gObjectList.mCloseObjects" << llendl; -						} -					} -				} - -				for( j = 0; j < gObjectList.mObjects.count(); j++ ) -				{ -					cur = &(gObjectList.mObjects[j]); -					if( cur == owner ) -					{ -						llinfos << "    gObjectList.mObjects" << llendl; -					} -				} - -				for( j = 0; j < gObjectList.mMapObjects.count(); j++ ) -				{ -					cur = &(gObjectList.mMapObjects[j]); -					if( cur == owner ) -					{ -						llinfos << "    gObjectList.mMapObjects" << llendl; -					} -				} -			} -		} -		*/  	}  } @@ -1316,11 +1214,10 @@ void LLVOAvatar::restoreGL()  	{  		LLVOAvatar* inst = (LLVOAvatar*) *iter;  		inst->setCompositeUpdatesEnabled( TRUE ); -		inst->invalidateComposite( inst->mHeadLayerSet,		FALSE ); -		inst->invalidateComposite( inst->mLowerBodyLayerSet,	FALSE ); -		inst->invalidateComposite( inst->mUpperBodyLayerSet,	FALSE ); -		inst->invalidateComposite( inst->mEyesLayerSet,	FALSE ); -		inst->invalidateComposite( inst->mSkirtLayerSet,	FALSE ); +		for (U32 i = 0; i < inst->mBakedTextureData.size(); i++) +		{ +			inst->invalidateComposite( inst->mBakedTextureData[i].mTexLayerSet, FALSE ); +		}  		inst->updateMeshTextures();  	}  } @@ -1345,7 +1242,7 @@ void LLVOAvatar::resetImpostors()  }  // static -void LLVOAvatar::deleteCachedImages() +void LLVOAvatar::deleteCachedImages(bool clearAll)  {  	if (LLTexLayerSet::sHasCaches)  	{ @@ -1354,12 +1251,12 @@ void LLVOAvatar::deleteCachedImages()  		iter != LLCharacter::sInstances.end(); ++iter)  		{  			LLVOAvatar* inst = (LLVOAvatar*) *iter; -			inst->deleteLayerSetCaches(); +			inst->deleteLayerSetCaches(clearAll);  		}  		LLTexLayerSet::sHasCaches = FALSE;  	} -	for( LLGLuint * namep = sScratchTexNames.getFirstData();  +	for( LLGLuint* namep = sScratchTexNames.getFirstData();   		 namep;   		 namep = sScratchTexNames.getNextData() )  	{ @@ -1387,8 +1284,6 @@ void LLVOAvatar::deleteCachedImages()  //------------------------------------------------------------------------  void LLVOAvatar::initClass()  {  -	LLVOAvatar::sMaxOtherAvatarsToComposite = gSavedSettings.getS32("AvatarCompositeLimit"); -  	std::string xmlFile;  	xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml"; @@ -1452,44 +1347,45 @@ void LLVOAvatar::initClass()  	// Process XML data  	// avatar_skeleton.xml -	llassert(!sSkeletonInfo); -	sSkeletonInfo = new LLVOAvatarSkeletonInfo; -	if (!sSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot())) +	llassert(!sAvatarSkeletonInfo); +	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo; +	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))  	{  		llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;  	}  	// parse avatar_lad.xml -	llassert(!sAvatarInfo); -	sAvatarInfo = new LLVOAvatarInfo; -	if (!sAvatarInfo->parseXmlSkeletonNode(root)) +	llassert(!sAvatarXmlInfo); +	sAvatarXmlInfo = new LLVOAvatarXmlInfo; +	if (!sAvatarXmlInfo->parseXmlSkeletonNode(root))  	{  		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;  	} -	if (!sAvatarInfo->parseXmlMeshNodes(root)) +	if (!sAvatarXmlInfo->parseXmlMeshNodes(root))  	{  		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;  	} -	if (!sAvatarInfo->parseXmlColorNodes(root)) +	if (!sAvatarXmlInfo->parseXmlColorNodes(root))  	{  		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;  	} -	if (!sAvatarInfo->parseXmlLayerNodes(root)) +	if (!sAvatarXmlInfo->parseXmlLayerNodes(root))  	{  		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;  	} -	if (!sAvatarInfo->parseXmlDriverNodes(root)) +	if (!sAvatarXmlInfo->parseXmlDriverNodes(root))  	{  		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;  	} +  }  void LLVOAvatar::cleanupClass()  { -	delete sAvatarInfo; -	sAvatarInfo = NULL; -	delete sSkeletonInfo; -	sSkeletonInfo = NULL; +	delete sAvatarXmlInfo; +	sAvatarXmlInfo = NULL; +	delete sAvatarSkeletonInfo; +	sAvatarSkeletonInfo = NULL;  	sSkeletonXMLTree.cleanup();  	sXMLTree.cleanup();  } @@ -1552,7 +1448,7 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)  	newMax = pos + buffer;  	//stretch bounding box by joint positions -	for (mesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i) +	for (polymesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i)  	{  		LLPolyMesh* mesh = i->second;  		for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++) @@ -1571,7 +1467,7 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)  	{  		LLViewerJointAttachment* attachment = iter->second; -		if(!attachment->getValid()) +		if (!attachment->getValid())  		{  			continue ;  		} @@ -1688,7 +1584,6 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	return FALSE;  } -  //-----------------------------------------------------------------------------  // parseSkeletonFile()  //----------------------------------------------------------------------------- @@ -1732,7 +1627,7 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)  //-----------------------------------------------------------------------------  // setupBone()  //----------------------------------------------------------------------------- -BOOL LLVOAvatar::setupBone(LLVOAvatarBoneInfo* info, LLViewerJoint* parent) +BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)  {  	LLMemType mt(LLMemType::MTYPE_AVATAR); @@ -1740,7 +1635,7 @@ BOOL LLVOAvatar::setupBone(LLVOAvatarBoneInfo* info, LLViewerJoint* parent)  	if (info->mIsJoint)  	{ -		joint = (LLViewerJoint*)getCharacterJoint(sCurJoint); +		joint = (LLViewerJoint*)getCharacterJoint(joint_num);  		if (!joint)  		{  			llwarns << "Too many bones" << llendl; @@ -1750,12 +1645,12 @@ BOOL LLVOAvatar::setupBone(LLVOAvatarBoneInfo* info, LLViewerJoint* parent)  	}  	else // collision volume  	{ -		if (sCurVolume >= (S32)mNumCollisionVolumes) +		if (volume_num >= (S32)mNumCollisionVolumes)  		{  			llwarns << "Too many bones" << llendl;  			return FALSE;  		} -		joint = (LLViewerJoint*)(&mCollisionVolumes[sCurVolume]); +		joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]);  		joint->setName( info->mName );  	} @@ -1777,19 +1672,19 @@ BOOL LLVOAvatar::setupBone(LLVOAvatarBoneInfo* info, LLViewerJoint* parent)  	if (info->mIsJoint)  	{  		joint->setSkinOffset( info->mPivot ); -		sCurJoint++; +		joint_num++;  	}  	else // collision volume  	{ -		sCurVolume++; +		volume_num++;  	}  	// setup children -	LLVOAvatarBoneInfo::child_list_t::iterator iter; +	LLVOAvatarBoneInfo::child_list_t::const_iterator iter;  	for (iter = info->mChildList.begin(); iter != info->mChildList.end(); iter++)  	{  		LLVOAvatarBoneInfo *child_info = *iter; -		if (!setupBone(child_info, joint)) +		if (!setupBone(child_info, joint, volume_num, joint_num))  		{  			return FALSE;  		} @@ -1801,7 +1696,7 @@ BOOL LLVOAvatar::setupBone(LLVOAvatarBoneInfo* info, LLViewerJoint* parent)  //-----------------------------------------------------------------------------  // buildSkeleton()  //----------------------------------------------------------------------------- -BOOL LLVOAvatar::buildSkeleton(LLVOAvatarSkeletonInfo *info) +BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)  {  	LLMemType mt(LLMemType::MTYPE_AVATAR); @@ -1826,14 +1721,13 @@ BOOL LLVOAvatar::buildSkeleton(LLVOAvatarSkeletonInfo *info)  		}  	} -	sCurJoint = 0; -	sCurVolume = 0; - -	LLVOAvatarSkeletonInfo::bone_info_list_t::iterator iter; +	S32 current_joint_num = 0; +	S32 current_volume_num = 0; +	LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;  	for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); iter++)  	{  		LLVOAvatarBoneInfo *info = *iter; -		if (!setupBone(info, NULL)) +		if (!setupBone(info, NULL, current_volume_num, current_joint_num))  		{  			llerrs << "Error parsing bone in skeleton file" << llendl;  			return FALSE; @@ -1899,43 +1793,17 @@ void LLVOAvatar::buildCharacter()  	//-------------------------------------------------------------------------  	// clear mesh data  	//------------------------------------------------------------------------- -	mHairMesh0.setMesh(NULL); -	mHairMesh1.setMesh(NULL); -	mHairMesh2.setMesh(NULL); -	mHairMesh3.setMesh(NULL); -	mHairMesh4.setMesh(NULL); -	mHairMesh5.setMesh(NULL); - -	mHeadMesh0.setMesh(NULL); -	mHeadMesh1.setMesh(NULL); -	mHeadMesh2.setMesh(NULL); -	mHeadMesh3.setMesh(NULL); -	mHeadMesh4.setMesh(NULL); - -	mEyeLashMesh0.setMesh(NULL); - -	mUpperBodyMesh0.setMesh(NULL); -	mUpperBodyMesh1.setMesh(NULL); -	mUpperBodyMesh2.setMesh(NULL); -	mUpperBodyMesh3.setMesh(NULL); -	mUpperBodyMesh4.setMesh(NULL); - -	mLowerBodyMesh0.setMesh(NULL); -	mLowerBodyMesh1.setMesh(NULL); -	mLowerBodyMesh2.setMesh(NULL); -	mLowerBodyMesh3.setMesh(NULL); -	mLowerBodyMesh4.setMesh(NULL); - -	mEyeBallLeftMesh0.setMesh(NULL); -	mEyeBallLeftMesh1.setMesh(NULL); -	mEyeBallRightMesh0.setMesh(NULL); -	mEyeBallRightMesh1.setMesh(NULL); - -	mSkirtMesh0.setMesh(NULL); -	mSkirtMesh1.setMesh(NULL); -	mSkirtMesh2.setMesh(NULL); -	mSkirtMesh3.setMesh(NULL); -	mSkirtMesh4.setMesh(NULL);	 +	for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin(); +		jointIter != mMeshLOD.end(); jointIter++) +	{ +		LLViewerJoint* joint = (LLViewerJoint*) *jointIter; +		for (std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin(); +			meshIter != joint->mMeshParts.end(); meshIter++) +		{ +			LLViewerJointMesh * mesh = (LLViewerJointMesh *) *meshIter; +			mesh->setMesh(NULL); +		} +	}  	//-------------------------------------------------------------------------  	// (re)load our skeleton and meshes @@ -2046,7 +1914,12 @@ void LLVOAvatar::buildCharacter()  	}  	startDefaultMotions(); -	 + +	//------------------------------------------------------------------------- +	// restart any currently active motions +	//------------------------------------------------------------------------- +	processAnimationStateChanges(); +  	mIsBuilt = TRUE;  	stop_glerror(); @@ -2260,21 +2133,18 @@ void LLVOAvatar::releaseMeshData()  	//llinfos << "Releasing" << llendl;  	// cleanup mesh data -	mHairLOD.setValid(FALSE, TRUE); -	mHeadLOD.setValid(FALSE, TRUE); -	mEyeLashLOD.setValid(FALSE, TRUE); -	mUpperBodyLOD.setValid(FALSE, TRUE); -	mLowerBodyLOD.setValid(FALSE, TRUE); -	mEyeBallLeftLOD.setValid(FALSE, TRUE); -	mEyeBallRightLOD.setValid(FALSE, TRUE); -	mSkirtLOD.setValid(FALSE, TRUE); +	for (std::vector<LLViewerJoint*>::iterator iter = mMeshLOD.begin(); +		iter != mMeshLOD.end(); iter++) +	{ +		LLViewerJoint* joint = (LLViewerJoint*) *iter; +		joint->setValid(FALSE, TRUE); +	}  	//cleanup data  	if (mDrawable.notNull())  	{  		LLFace* facep = mDrawable->getFace(0);  		facep->setSize(0, 0); -  		for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)  		{  			facep = mDrawable->getFace(i); @@ -2337,34 +2207,25 @@ void LLVOAvatar::updateMeshData()  	{  		stop_glerror(); -		LLViewerJoint* av_parts[8] ; -		av_parts[0] = &mEyeBallLeftLOD ; -		av_parts[1] = &mEyeBallRightLOD ; -		av_parts[2] = &mEyeLashLOD ; -		av_parts[3] = &mHeadLOD ; -		av_parts[4] = &mLowerBodyLOD ; -		av_parts[5] = &mSkirtLOD ; -		av_parts[6] = &mUpperBodyLOD ; -		av_parts[7] = &mHairLOD ; -		  		S32 f_num = 0 ;  		const U32 VERTEX_NUMBER_THRESHOLD = 128 ;//small number of this means each part of an avatar has its own vertex buffer. +		const S32 num_parts = mMeshLOD.size();  		// this order is determined by number of LODS  		// if a mesh earlier in this list changed LODs while a later mesh doesn't,  		// the later mesh's index offset will be inaccurate -		for(S32 part_index = 0 ; part_index < 8 ;) +		for(S32 part_index = 0 ; part_index < num_parts ;)  		{  			S32 j = part_index ;  			U32 last_v_num = 0, num_vertices = 0 ;  			U32 last_i_num = 0, num_indices = 0 ; -			while(part_index < 8 && num_vertices < VERTEX_NUMBER_THRESHOLD) +			while(part_index < num_parts && num_vertices < VERTEX_NUMBER_THRESHOLD)  			{  				last_v_num = num_vertices ;  				last_i_num = num_indices ; -				av_parts[part_index++]->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); +				mMeshLOD[part_index++]->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);  			}  			if(num_vertices < 1)//skip empty meshes  			{ @@ -2412,7 +2273,7 @@ void LLVOAvatar::updateMeshData()  			for(S32 k = j ; k < part_index ; k++)  			{ -				av_parts[k]->updateFaceData(facep, mAdjustedPixelArea, (k == 7)); +				mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR);  			}  			stop_glerror(); @@ -2536,27 +2397,6 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,  	//llinfos << getRotation() << llendl;  	//llinfos << getPosition() << llendl; -	if (update_type == OUT_FULL ) -	{ -		if( !mIsSelf || !mFirstTEMessageReceived ) -		{ -//			dumpAvatarTEs( "PRE   processUpdateMessage()" ); -			unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); -//			dumpAvatarTEs( "POST  processUpdateMessage()" ); - -			if( !mFirstTEMessageReceived ) -			{ -				onFirstTEMessageReceived(); -			} - -			// Disable updates to composites.  We'll decide whether we need to do -			// any updates after we find out whether this update message has any -			// "baked" (pre-composited) textures. -			setCompositeUpdatesEnabled( FALSE ); -			updateMeshTextures();  -			setCompositeUpdatesEnabled( TRUE ); -		} -	}  	return retval;  } @@ -2566,7 +2406,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)  {  	// The core setTETexture() method requests images, so we need  	// to redirect certain avatar texture requests to different sims. -	if (isTextureIndexBaked(te)) +	if (isIndexBakedTexture((ETextureIndex)te))  	{  		LLHost target_host = getObjectHost();  		return setTETextureCore(te, uuid, target_host); @@ -2865,15 +2705,12 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)  		}  	} -	if (mDrawable.notNull()) +	mDrawable->movePartition(); +	 +	//force a move if sitting on an active object +	if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive())  	{ -		mDrawable->movePartition(); -		 -		//force a move if sitting on an active object -		if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) -		{ -			gPipeline.markMoved(mDrawable, TRUE); -		} +		gPipeline.markMoved(mDrawable, TRUE);  	}  } @@ -3765,7 +3602,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  			F32 root_roll, root_pitch, root_yaw;  			root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw); -			if (gDebugAvatarRotation) +			if (sDebugAvatarRotation)  			{  				llinfos << "root_roll " << RAD_TO_DEG * root_roll   					<< " root_pitch " << RAD_TO_DEG * root_pitch @@ -3955,7 +3792,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  //							AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );  			const F32 STEP_VOLUME = 0.5f; -			LLUUID& step_sound_id = getStepSound(); +			const LLUUID& step_sound_id = getStepSound();  			LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent); @@ -4189,19 +4026,19 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  		if (mNeedsSkin)  		{  			//generate animated mesh -			mLowerBodyLOD.updateJointGeometry(); -			mUpperBodyLOD.updateJointGeometry(); +			mMeshLOD[MESH_ID_LOWER_BODY]->updateJointGeometry(); +			mMeshLOD[MESH_ID_UPPER_BODY]->updateJointGeometry();  			if( isWearingWearableType( WT_SKIRT ) )  			{ -				mSkirtLOD.updateJointGeometry(); +				mMeshLOD[MESH_ID_SKIRT]->updateJointGeometry();  			}  			if (!mIsSelf || gAgent.needsRenderHead() || LLPipeline::sShadowRender)  			{ -				mEyeLashLOD.updateJointGeometry(); -				mHeadLOD.updateJointGeometry(); -				mHairLOD.updateJointGeometry();				 +				mMeshLOD[MESH_ID_EYELASH]->updateJointGeometry(); +				mMeshLOD[MESH_ID_HEAD]->updateJointGeometry(); +				mMeshLOD[MESH_ID_HAIR]->updateJointGeometry();  			}  			mNeedsSkin = FALSE; @@ -4289,7 +4126,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  		gGL.flush();  	}  	//-------------------------------------------------------------------- -	// render all geomety attached to the skeleton +	// render all geometry attached to the skeleton  	//--------------------------------------------------------------------  	static LLStat render_stat; @@ -4297,18 +4134,42 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  	if (pass == AVATAR_RENDER_PASS_SINGLE)  	{ +		bool should_alpha_mask = mHasBakedHair && isTextureDefined(TEX_HEAD_BAKED) && isTextureDefined(TEX_UPPER_BAKED)  +								&& isTextureDefined(TEX_LOWER_BAKED) && mBakedTextureData[BAKED_HEAD].mIsLoaded +								&& mBakedTextureData[BAKED_UPPER].mIsLoaded && mBakedTextureData[BAKED_LOWER].mIsLoaded; +		LLGLState test(GL_ALPHA_TEST, should_alpha_mask); + +		if (should_alpha_mask) +		{ +			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); +		} +		  		BOOL first_pass = TRUE;  		if (!LLDrawPoolAvatar::sSkipOpaque)  		{  			if (!mIsSelf || gAgent.needsRenderHead() || LLPipeline::sShadowRender)  			{ -				num_indices += mHeadLOD.render(mAdjustedPixelArea); +				if (isTextureVisible(TEX_HEAD_BAKED)) +				{ +					num_indices += mMeshLOD[MESH_ID_HEAD]->render(mAdjustedPixelArea); +					first_pass = FALSE; +				} +			} +			if (isTextureVisible(TEX_UPPER_BAKED)) +			{ +				num_indices += mMeshLOD[MESH_ID_UPPER_BODY]->render(mAdjustedPixelArea, first_pass); +				first_pass = FALSE; +			} +			 +			if (isTextureVisible(TEX_LOWER_BAKED)) +			{ +				num_indices += mMeshLOD[MESH_ID_LOWER_BODY]->render(mAdjustedPixelArea, first_pass);  				first_pass = FALSE;  			} -			num_indices += mUpperBodyLOD.render(mAdjustedPixelArea, first_pass); -			num_indices += mLowerBodyLOD.render(mAdjustedPixelArea, FALSE);  		} +		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +  		if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender)  		{  			LLGLEnable blend(GL_BLEND); @@ -4329,10 +4190,10 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  U32 LLVOAvatar::renderTransparent(BOOL first_pass)  {  	U32 num_indices = 0; -	if( isWearingWearableType( WT_SKIRT ) ) +	if( isWearingWearableType( WT_SKIRT ) && isTextureVisible(TEX_SKIRT_BAKED) )  	{  		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f); -		num_indices += mSkirtLOD.render(mAdjustedPixelArea, FALSE); +		num_indices += mMeshLOD[MESH_ID_SKIRT]->render(mAdjustedPixelArea, FALSE);  		first_pass = FALSE;  		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  	} @@ -4343,8 +4204,17 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)  		{  			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);  		} -		num_indices += mEyeLashLOD.render(mAdjustedPixelArea, first_pass); -		num_indices += mHairLOD.render(mAdjustedPixelArea, FALSE); +		 +		if (isTextureVisible(TEX_HEAD_BAKED)) +		{ +			num_indices += mMeshLOD[MESH_ID_EYELASH]->render(mAdjustedPixelArea, first_pass); +			first_pass = FALSE; +		} +		if (isTextureVisible(TEX_HAIR_BAKED)) +		{ +			num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass); +			first_pass = FALSE; +		}  		if (LLPipeline::sImpostorRender)  		{  			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); @@ -4376,8 +4246,22 @@ U32 LLVOAvatar::renderRigid()  		return 0;  	} -	num_indices += mEyeBallLeftLOD.render(mAdjustedPixelArea); -	num_indices += mEyeBallRightLOD.render(mAdjustedPixelArea); +	if (isTextureVisible(TEX_EYES_BAKED)) +	{ +		// If the meshes need to be drawn, enable alpha masking but not blending +		bool should_alpha_mask = mHasBakedHair && mBakedTextureData[BAKED_EYES].mIsLoaded; +		LLGLState test(GL_ALPHA_TEST, should_alpha_mask); +		 +		if (should_alpha_mask) +		{ +			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); +		} + +		num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea); +		num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea); + +		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +	}  	return num_indices;  } @@ -4400,6 +4284,13 @@ U32 LLVOAvatar::renderFootShadows()  	{  		return 0;  	} +	 +	// Don't render foot shadows if your lower body is completely invisible. +	// (non-humanoid avatars rule!) +	if (! isTextureVisible(TEX_LOWER_BAKED)) +	{ +		return 0; +	}  	// Update the shadow, tractor, and text label geometry.  	if (mDrawable->isState(LLDrawable::REBUILD_SHADOW) && !isImpostor()) @@ -4470,12 +4361,6 @@ void LLVOAvatar::updateTextures(LLAgent &agent)  	{  		return;  	} -	 -	BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR );  	if( mIsSelf )  	{ @@ -4486,30 +4371,18 @@ void LLVOAvatar::updateTextures(LLAgent &agent)  		render_avatar = isVisible() && !mCulled;  	} -	// bind the texture so that they'll be decoded -	// slightly inefficient, we can short-circuit this -	// if we have to -	if( render_avatar && !gGLManager.mIsDisabled ) +	std::vector<bool> layer_baked; +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		if( head_baked && ! mHeadBakedLoaded ) -		{ -			gGL.getTexUnit(0)->bind(getTEImage( TEX_HEAD_BAKED )); -		} -		if( upper_baked && ! mUpperBakedLoaded ) -		{ -			gGL.getTexUnit(0)->bind(getTEImage( TEX_UPPER_BAKED )); -		} -		if( lower_baked && ! mLowerBakedLoaded ) -		{ -			gGL.getTexUnit(0)->bind(getTEImage( TEX_LOWER_BAKED )); -		} -		if( eyes_baked && ! mEyesBakedLoaded ) -		{ -			gGL.getTexUnit(0)->bind(getTEImage( TEX_EYES_BAKED )); -		} -		if( skirt_baked && ! mSkirtBakedLoaded ) +		layer_baked.push_back(isTextureDefined(mBakedTextureData[i].mTextureIndex)); +		// bind the texture so that they'll be decoded slightly  +		// inefficient, we can short-circuit this if we have to +		if( render_avatar && !gGLManager.mIsDisabled )  		{ -			gGL.getTexUnit(0)->bind(getTEImage( TEX_SKIRT_BAKED )); +			if (layer_baked[i] && !mBakedTextureData[i].mIsLoaded) +			{ +				gGL.getTexUnit(0)->bind(getTEImage( mBakedTextureData[i].mTextureIndex )); +			}  		}  	} @@ -4541,9 +4414,9 @@ void LLVOAvatar::updateTextures(LLAgent &agent)  	mMaxPixelArea = 0.f;  	mMinPixelArea = 99999999.f;  	mHasGrey = FALSE; // debug -	for (U32 i = 0; i < getNumTEs(); i++) +	for (U32 index = 0; index < getNumTEs(); index++)  	{ -		LLViewerImage *imagep = getTEImage(i); +		LLViewerImage *imagep = getTEImage(index);  		if (imagep)  		{  			// Debugging code - maybe non-self avatars are downloading textures? @@ -4555,131 +4428,39 @@ void LLVOAvatar::updateTextures(LLAgent &agent)  			//	<< " desired " << imagep->getDesiredDiscardLevel()  			//	<< llendl; -			const LLTextureEntry *te = getTE(i); +			const LLTextureEntry *te = getTE(index);  			F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT);  			S32 boost_level = mIsSelf ? LLViewerImage::BOOST_AVATAR_BAKED_SELF : LLViewerImage::BOOST_AVATAR_BAKED;  			// Spam if this is a baked texture, not set to default image, without valid host info -			if (isTextureIndexBaked(i) +			if (isIndexBakedTexture((ETextureIndex)index)  				&& imagep->getID() != IMG_DEFAULT_AVATAR  				&& !imagep->getTargetHost().isOk())  			{ -				llwarns << "LLVOAvatar::updateTextures No host for texture " +				LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture "  					<< imagep->getID() << " for avatar "  					<< (mIsSelf ? "<myself>" : getID().asString())   					<< " on host " << getRegion()->getHost() << llendl;  			} -			 -			switch( i ) -			{ -			// Head -			case TEX_HEAD_BODYPAINT: -				addLocalTextureStats( LOCTEX_HEAD_BODYPAINT, imagep, texel_area_ratio, render_avatar, head_baked ); -				break; - -			// Upper -			case TEX_UPPER_JACKET: -				addLocalTextureStats( LOCTEX_UPPER_JACKET, imagep, texel_area_ratio, render_avatar, upper_baked ); -				break; - -			case TEX_UPPER_SHIRT: -				addLocalTextureStats( LOCTEX_UPPER_SHIRT, imagep, texel_area_ratio, render_avatar, upper_baked ); -				break; - -			case TEX_UPPER_GLOVES: -				addLocalTextureStats( LOCTEX_UPPER_GLOVES, imagep, texel_area_ratio, render_avatar, upper_baked ); -				break; -			 -			case TEX_UPPER_UNDERSHIRT: -				addLocalTextureStats( LOCTEX_UPPER_UNDERSHIRT, imagep, texel_area_ratio, render_avatar, upper_baked ); -				break; - -			case TEX_UPPER_BODYPAINT: -				addLocalTextureStats( LOCTEX_UPPER_BODYPAINT, imagep, texel_area_ratio, render_avatar, upper_baked ); -				break; -			// Lower -			case TEX_LOWER_JACKET: -				addLocalTextureStats( LOCTEX_LOWER_JACKET, imagep, texel_area_ratio, render_avatar, lower_baked ); -				break; - -			case TEX_LOWER_PANTS: -				addLocalTextureStats( LOCTEX_LOWER_PANTS, imagep, texel_area_ratio, render_avatar, lower_baked ); -				break; - -			case TEX_LOWER_SHOES: -				addLocalTextureStats( LOCTEX_LOWER_SHOES, imagep, texel_area_ratio, render_avatar, lower_baked ); -				break; - -			case TEX_LOWER_SOCKS: -				addLocalTextureStats( LOCTEX_LOWER_SOCKS, imagep, texel_area_ratio, render_avatar, lower_baked ); -				break; - -			case TEX_LOWER_UNDERPANTS: -				addLocalTextureStats( LOCTEX_LOWER_UNDERPANTS, imagep, texel_area_ratio, render_avatar, lower_baked ); -				break; - -			case TEX_LOWER_BODYPAINT: -				addLocalTextureStats( LOCTEX_LOWER_BODYPAINT, imagep, texel_area_ratio, render_avatar, lower_baked ); -				break; - -			// Eyes -			case TEX_EYES_IRIS: -				addLocalTextureStats( LOCTEX_EYES_IRIS, imagep, texel_area_ratio, render_avatar, eyes_baked ); -				break; - -			// Skirt -			case TEX_SKIRT: -				addLocalTextureStats( LOCTEX_SKIRT, imagep, texel_area_ratio, render_avatar, skirt_baked ); -				break; - -			// Baked -			case TEX_HEAD_BAKED: -				if (head_baked) -				{ -					addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); -				} -				break; - -			case TEX_UPPER_BAKED: -				if (upper_baked) -				{ -					addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); -				} -				break; -			 -			case TEX_LOWER_BAKED: -				if (lower_baked) -				{ -					addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); -				} -				break; -			 -			case TEX_EYES_BAKED: -				if (eyes_baked) +			/* switch(index) +				case TEX_HEAD_BODYPAINT: +					addLocalTextureStats( LOCTEX_HEAD_BODYPAINT, imagep, texel_area_ratio, render_avatar, head_baked ); */ +			const LLVOAvatarDictionary::TextureDictionaryEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)index); +			if (texture_dict->mIsUsedByBakedTexture) +			{ +				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; +				if (texture_dict->mIsLocalTexture)  				{ -					addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); +					addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]);  				} -				break; - -			case TEX_SKIRT_BAKED: -				if (skirt_baked) +				else if (texture_dict->mIsBakedTexture)  				{ -					addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); +					if (layer_baked[baked_index]) +					{ +						addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); +					}  				} -				break; - -			case TEX_HAIR: -				// Hair is neither a local texture used for baking, nor the output -				// of the baking process.  It's just a texture that happens to be -				// used to draw avatars.  Hence BOOST_AVATAR.  JC -			  	boost_level = mIsSelf ? LLViewerImage::BOOST_AVATAR_SELF : LLViewerImage::BOOST_AVATAR; -			  	addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); -				break; -			 -			default: -				llassert(0); -				break;  			}  		}  	} @@ -4696,22 +4477,24 @@ void LLVOAvatar::updateTextures(LLAgent &agent)  } -void LLVOAvatar::addLocalTextureStats( LLVOAvatar::ELocTexIndex idx, LLViewerImage* imagep, +void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerImage* imagep,  									   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked )  { +	if (!isIndexLocalTexture(idx)) return; +  	if (!covered_by_baked && render_avatar) // render_avatar is always true if mIsSelf  	{ -		if (mLocalTexture[ idx ].notNull() && mLocalTexture[idx]->getID() != IMG_DEFAULT_AVATAR) +		if (getLocalTextureID(idx) != IMG_DEFAULT_AVATAR)  		{  			F32 desired_pixels;  			if( mIsSelf )  			{ -				desired_pixels = llmin(mPixelArea, (F32)LOCTEX_IMAGE_AREA_SELF ); +				desired_pixels = llmin(mPixelArea, (F32)TEX_IMAGE_AREA_SELF );  				imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR_SELF);  			}  			else  			{ -				desired_pixels = llmin(mPixelArea, (F32)LOCTEX_IMAGE_AREA_OTHER ); +				desired_pixels = llmin(mPixelArea, (F32)TEX_IMAGE_AREA_OTHER );  				imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR);  			}  			imagep->addTextureStats( desired_pixels / texel_area_ratio ); @@ -4722,11 +4505,8 @@ void LLVOAvatar::addLocalTextureStats( LLVOAvatar::ELocTexIndex idx, LLViewerIma  		}  		else  		{ -			if (mLocalTexture[idx]->getID() == IMG_DEFAULT_AVATAR) -			{ -				// texture asset is missing -				mHasGrey = TRUE; // for statistics gathering -			} +			// texture asset is missing +			mHasGrey = TRUE; // for statistics gathering  		}  	}  } @@ -4794,7 +4574,7 @@ void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos  //-----------------------------------------------------------------------------  // getStepSound()  //----------------------------------------------------------------------------- -LLUUID& LLVOAvatar::getStepSound() +const LLUUID& LLVOAvatar::getStepSound() const  {  	if ( mStepOnLand )  	{ @@ -5232,7 +5012,7 @@ F32 LLVOAvatar::getPixelArea() const  //-----------------------------------------------------------------------------  LLPolyMesh*	LLVOAvatar::getHeadMesh()  { -	return mHeadMesh0.getMesh(); +	return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh();  } @@ -5241,7 +5021,7 @@ LLPolyMesh*	LLVOAvatar::getHeadMesh()  //-----------------------------------------------------------------------------  LLPolyMesh*	LLVOAvatar::getUpperBodyMesh()  { -	return mUpperBodyMesh0.getMesh(); +	return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh();  } @@ -5340,7 +5120,7 @@ BOOL LLVOAvatar::loadAvatar()  // 	LLFastTimer t(LLFastTimer::FTM_LOAD_AVATAR);  	// avatar_skeleton.xml -	if( !buildSkeleton(sSkeletonInfo) ) +	if( !buildSkeleton(sAvatarSkeletonInfo) )  	{  		llwarns << "avatar file: buildSkeleton() failed" << llendl;  		return FALSE; @@ -5361,10 +5141,10 @@ BOOL LLVOAvatar::loadAvatar()  	}  	// avatar_lad.xml : <global_color> -	if( sAvatarInfo->mTexSkinColorInfo ) +	if( sAvatarXmlInfo->mTexSkinColorInfo )  	{  		mTexSkinColor = new LLTexGlobalColor( this ); -		if( !mTexSkinColor->setInfo( sAvatarInfo->mTexSkinColorInfo ) ) +		if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) )  		{  			llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl;  			return FALSE; @@ -5375,10 +5155,10 @@ BOOL LLVOAvatar::loadAvatar()  		llwarns << "<global_color> name=\"skin_color\" not found" << llendl;  		return FALSE;  	} -	if( sAvatarInfo->mTexHairColorInfo ) +	if( sAvatarXmlInfo->mTexHairColorInfo )  	{  		mTexHairColor = new LLTexGlobalColor( this ); -		if( !mTexHairColor->setInfo( sAvatarInfo->mTexHairColorInfo ) ) +		if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) )  		{  			llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl;  			return FALSE; @@ -5389,10 +5169,10 @@ BOOL LLVOAvatar::loadAvatar()  		llwarns << "<global_color> name=\"hair_color\" not found" << llendl;  		return FALSE;  	} -	if( sAvatarInfo->mTexEyeColorInfo ) +	if( sAvatarXmlInfo->mTexEyeColorInfo )  	{  		mTexEyeColor = new LLTexGlobalColor( this ); -		if( !mTexEyeColor->setInfo( sAvatarInfo->mTexEyeColorInfo ) ) +		if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) )  		{  			llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl;  			return FALSE; @@ -5405,15 +5185,15 @@ BOOL LLVOAvatar::loadAvatar()  	}  	// avatar_lad.xml : <layer_set> -	if (sAvatarInfo->mLayerInfoList.empty()) +	if (sAvatarXmlInfo->mLayerInfoList.empty())  	{  		llwarns << "avatar file: missing <layer_set> node" << llendl;  	}  	else  	{ -		LLVOAvatarInfo::layer_info_list_t::iterator iter; -		for (iter = sAvatarInfo->mLayerInfoList.begin(); -			 iter != sAvatarInfo->mLayerInfoList.end(); iter++) +		LLVOAvatarXmlInfo::layer_info_list_t::iterator iter; +		for (iter = sAvatarXmlInfo->mLayerInfoList.begin(); +			 iter != sAvatarXmlInfo->mLayerInfoList.end(); iter++)  		{  			LLTexLayerSetInfo *info = *iter;  			LLTexLayerSet* layer_set = new LLTexLayerSet( this ); @@ -5424,27 +5204,20 @@ BOOL LLVOAvatar::loadAvatar()  				llwarns << "avatar file: layer_set->parseData() failed" << llendl;  				return FALSE;  			} -			if( layer_set->isBodyRegion( "head" ) ) +			bool found_baked_entry = false; +			for (LLVOAvatarDictionary::baked_map_t::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); +				 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); +				 baked_iter++)  			{ -				mHeadLayerSet = layer_set; -			} -			else if( layer_set->isBodyRegion( "upper_body" ) ) -			{ -				mUpperBodyLayerSet = layer_set; -			} -			else if( layer_set->isBodyRegion( "lower_body" ) ) -			{ -				mLowerBodyLayerSet = layer_set; -			} -			else if( layer_set->isBodyRegion( "eyes" ) ) -			{ -				mEyesLayerSet = layer_set; -			} -			else if( layer_set->isBodyRegion( "skirt" ) ) -			{ -				mSkirtLayerSet = layer_set; +				const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = baked_iter->second; +				if (layer_set->isBodyRegion(baked_dict->mName)) +				{ +					mBakedTextureData[baked_iter->first].mTexLayerSet = layer_set; +					found_baked_entry = true; +					break; +				}  			} -			else +			if (!found_baked_entry)  			{  				llwarns << "<layer_set> has invalid body_region attribute" << llendl;  				delete layer_set; @@ -5455,9 +5228,9 @@ BOOL LLVOAvatar::loadAvatar()  	// avatar_lad.xml : <driver_parameters>  	{ -		LLVOAvatarInfo::driver_info_list_t::iterator iter; -		for (iter = sAvatarInfo->mDriverInfoList.begin(); -			 iter != sAvatarInfo->mDriverInfoList.end(); iter++) +		LLVOAvatarXmlInfo::driver_info_list_t::iterator iter; +		for (iter = sAvatarXmlInfo->mDriverInfoList.begin(); +			 iter != sAvatarXmlInfo->mDriverInfoList.end(); iter++)  		{  			LLDriverParamInfo *info = *iter;  			LLDriverParam* driver_param = new LLDriverParam( this ); @@ -5484,78 +5257,44 @@ BOOL LLVOAvatar::loadSkeletonNode ()  {  	mRoot.addChild( &mSkeleton[0] ); -	mRoot.addChild( &mHeadLOD ); -		mHeadLOD.mUpdateXform = FALSE; -		mHeadLOD.addChild( &mHeadMesh0 ); -		mHeadLOD.addChild( &mHeadMesh1 ); -		mHeadLOD.addChild( &mHeadMesh2 ); -		mHeadLOD.addChild( &mHeadMesh3 ); -		mHeadLOD.addChild( &mHeadMesh4 ); -	 -	mRoot.addChild( &mEyeLashLOD ); -		mEyeLashLOD.mUpdateXform = FALSE; -		mEyeLashLOD.addChild( &mEyeLashMesh0 ); - -	mRoot.addChild( &mUpperBodyLOD ); -		mUpperBodyLOD.mUpdateXform = FALSE; -		mUpperBodyLOD.addChild( &mUpperBodyMesh0 ); -		mUpperBodyLOD.addChild( &mUpperBodyMesh1 ); -		mUpperBodyLOD.addChild( &mUpperBodyMesh2 ); -		mUpperBodyLOD.addChild( &mUpperBodyMesh3 ); -		mUpperBodyLOD.addChild( &mUpperBodyMesh4 ); - -	mRoot.addChild( &mLowerBodyLOD ); -		mLowerBodyLOD.mUpdateXform = FALSE; -		mLowerBodyLOD.addChild( &mLowerBodyMesh0 ); -		mLowerBodyLOD.addChild( &mLowerBodyMesh1 ); -		mLowerBodyLOD.addChild( &mLowerBodyMesh2 ); -		mLowerBodyLOD.addChild( &mLowerBodyMesh3 ); -		mLowerBodyLOD.addChild( &mLowerBodyMesh4 ); - -	mRoot.addChild( &mSkirtLOD ); -		mSkirtLOD.mUpdateXform = FALSE; -		mSkirtLOD.addChild( &mSkirtMesh0 ); -		mSkirtLOD.addChild( &mSkirtMesh1 ); -		mSkirtLOD.addChild( &mSkirtMesh2 ); -		mSkirtLOD.addChild( &mSkirtMesh3 ); -		mSkirtLOD.addChild( &mSkirtMesh4 ); +	for (std::vector<LLViewerJoint *>::iterator iter = mMeshLOD.begin(); +		iter != mMeshLOD.end(); iter++) +	{ +		LLViewerJoint *joint = (LLViewerJoint *) *iter; +		joint->mUpdateXform = FALSE; +		joint->setMeshesToChildren(); +	} + +	mRoot.addChild(mMeshLOD[MESH_ID_HEAD]); +	mRoot.addChild(mMeshLOD[MESH_ID_EYELASH]); +	mRoot.addChild(mMeshLOD[MESH_ID_UPPER_BODY]); +	mRoot.addChild(mMeshLOD[MESH_ID_LOWER_BODY]); +	mRoot.addChild(mMeshLOD[MESH_ID_SKIRT]); +	mRoot.addChild(mMeshLOD[MESH_ID_HEAD]);  	LLViewerJoint *skull = (LLViewerJoint*)mRoot.findJoint("mSkull");  	if (skull)  	{ -		skull->addChild( &mHairLOD ); -			mHairLOD.mUpdateXform = FALSE; -			mHairLOD.addChild( &mHairMesh0 ); -			mHairLOD.addChild( &mHairMesh1 ); -			mHairLOD.addChild( &mHairMesh2 ); -			mHairLOD.addChild( &mHairMesh3 ); -			mHairLOD.addChild( &mHairMesh4 ); -			mHairLOD.addChild( &mHairMesh5 ); +		skull->addChild(mMeshLOD[MESH_ID_HAIR] );  	}  	LLViewerJoint *eyeL = (LLViewerJoint*)mRoot.findJoint("mEyeLeft");  	if (eyeL)  	{ -		eyeL->addChild( &mEyeBallLeftLOD ); -			mEyeBallLeftLOD.mUpdateXform = FALSE; -			mEyeBallLeftLOD.addChild( &mEyeBallLeftMesh0 ); -			mEyeBallLeftLOD.addChild( &mEyeBallLeftMesh1 ); +		eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );  	}  	LLViewerJoint *eyeR = (LLViewerJoint*)mRoot.findJoint("mEyeRight");  	if (eyeR)  	{ -		eyeR->addChild( &mEyeBallRightLOD ); -			mEyeBallRightLOD.mUpdateXform = FALSE; -			mEyeBallRightLOD.addChild( &mEyeBallRightMesh0 ); -			mEyeBallRightLOD.addChild( &mEyeBallRightMesh1 ); +		eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );  	}  	// SKELETAL DISTORTIONS  	{ -		LLVOAvatarInfo::skeletal_distortion_info_list_t::iterator iter; -		for (iter = sAvatarInfo->mSkeletalDistortionInfoList.begin(); -			 iter != sAvatarInfo->mSkeletalDistortionInfoList.end(); iter++) +		LLVOAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter; +		for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin(); +			 iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); iter++)  		{  			LLPolySkeletalDistortionInfo *info = *iter;  			LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this); @@ -5573,11 +5312,11 @@ BOOL LLVOAvatar::loadSkeletonNode ()  	// ATTACHMENTS  	{ -		LLVOAvatarInfo::attachment_info_list_t::iterator iter; -		for (iter = sAvatarInfo->mAttachmentInfoList.begin(); -			 iter != sAvatarInfo->mAttachmentInfoList.end(); iter++) +		LLVOAvatarXmlInfo::attachment_info_list_t::iterator iter; +		for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin(); +			 iter != sAvatarXmlInfo->mAttachmentInfoList.end(); iter++)  		{ -			LLVOAvatarInfo::LLVOAvatarAttachmentInfo *info = *iter; +			LLVOAvatarXmlInfo::LLVOAvatarAttachmentInfo *info = *iter;  			if (!isSelf() && info->mJointName == "mScreen")  			{ //don't process screen joint for other avatars  				continue; @@ -5654,174 +5393,49 @@ BOOL LLVOAvatar::loadSkeletonNode ()  //-----------------------------------------------------------------------------  BOOL LLVOAvatar::loadMeshNodes()  { -	LLVOAvatarInfo::mesh_info_list_t::iterator iter; -	for (iter = sAvatarInfo->mMeshInfoList.begin(); -		 iter != sAvatarInfo->mMeshInfoList.end(); iter++) +	for (LLVOAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin(); +		 meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end();  +		 meshinfo_iter++)  	{ -		LLVOAvatarInfo::LLVOAvatarMeshInfo *info = *iter; -		std::string &type = info->mType; +		const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo *info = *meshinfo_iter; +		const std::string &type = info->mType;  		S32 lod = info->mLOD;  		LLViewerJointMesh* mesh = NULL; -		if (type == "hairMesh") -		{ -			switch (lod) -			{ -			  case 0: -				mesh = &mHairMesh0; -				break; -			  case 1: -				mesh = &mHairMesh1; -				break; -			  case 2: -				mesh = &mHairMesh2; -				break; -			  case 3: -				mesh = &mHairMesh3; -				break; -			  case 4: -				mesh = &mHairMesh4; -				break; -			  case 5: -				mesh = &mHairMesh5; -				break; -			  default: -				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; -				return FALSE; -			} -		} -		else if (type == "headMesh") -		{ -			switch (lod) -			{ +		U8 mesh_id = 0; +		BOOL found_mesh_id = FALSE; + +		/* if (type == "hairMesh") +			switch(lod)  			  case 0: -				mesh = &mHeadMesh0; -				break; -			  case 1: -				mesh = &mHeadMesh1; -				break; -			  case 2: -				mesh = &mHeadMesh2; -				break; -			  case 3: -				mesh = &mHeadMesh3; -				break; -			  case 4: -				mesh = &mHeadMesh4; -				break; -			  default: -				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; -				return FALSE; -			} -		} -		else if (type == "upperBodyMesh") +				mesh = &mHairMesh0; */ +		for (LLVOAvatarDictionary::mesh_map_t::const_iterator mesh_iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin(); +			 mesh_iter != LLVOAvatarDictionary::getInstance()->getMeshes().end(); +			 mesh_iter++)  		{ -			switch (lod) +			const EMeshIndex mesh_index = mesh_iter->first; +			const LLVOAvatarDictionary::MeshDictionaryEntry *mesh_dict = mesh_iter->second; +			if (type.compare(mesh_dict->mName) == 0)  			{ -			  case 0: -				mesh = &mUpperBodyMesh0; -				break; -			  case 1: -				mesh = &mUpperBodyMesh1; -				break; -			  case 2: -				mesh = &mUpperBodyMesh2; -				break; -			  case 3: -				mesh = &mUpperBodyMesh3; -				break; -			  case 4: -				mesh = &mUpperBodyMesh4; +				mesh_id = mesh_index; +				found_mesh_id = TRUE;  				break; -			  default: -				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; -				return FALSE;  			}  		} -		else if (type == "lowerBodyMesh") -		{ -			switch (lod) -			{ -			  case 0: -				mesh = &mLowerBodyMesh0; -				break; -			  case 1: -				mesh = &mLowerBodyMesh1; -				break; -			  case 2: -				mesh = &mLowerBodyMesh2; -				break; -			  case 3: -				mesh = &mLowerBodyMesh3; -				break; -			  case 4: -				mesh = &mLowerBodyMesh4; -				break; -			  default: -				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; -				return FALSE; -			} -		}	 -		else if (type == "skirtMesh") -		{ -			switch (lod) -			{ -			  case 0: -				mesh = &mSkirtMesh0; -				break; -			  case 1: -				mesh = &mSkirtMesh1; -				break; -			  case 2: -				mesh = &mSkirtMesh2; -				break; -			  case 3: -				mesh = &mSkirtMesh3; -				break; -			  case 4: -				mesh = &mSkirtMesh4; -				break; -			  default: -				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; -				return FALSE; -			} -		} -		else if (type == "eyelashMesh") -		{ -			mesh = &mEyeLashMesh0; -		} -		else if (type == "eyeBallLeftMesh") + +		if (found_mesh_id)  		{ -			switch (lod) +			if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size())  			{ -			  case 0: -				mesh = &mEyeBallLeftMesh0; -				break; -			  case 1: -				mesh = &mEyeBallLeftMesh1; -				break; -			  default: -				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; -				return FALSE; +				mesh = mMeshLOD[mesh_id]->mMeshParts[lod];  			} -		} -		else if (type == "eyeBallRightMesh") -		{ -			switch (lod) +			else  			{ -			  case 0: -				mesh = &mEyeBallRightMesh0; -				break; -			  case 1: -				mesh = &mEyeBallRightMesh1; -				break; -			  default:  				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;  				return FALSE;  			}  		} - -		if( !mesh ) +		else   		{  			llwarns << "Ignoring unrecognized mesh type: " << type << llendl;  			return FALSE; @@ -5837,15 +5451,16 @@ BOOL LLVOAvatar::loadMeshNodes()  		if (!info->mReferenceMeshName.empty())  		{ -			mesh_map_t::iterator iter = mMeshes.find(info->mReferenceMeshName); -			if (iter != mMeshes.end()) +			polymesh_map_t::const_iterator polymesh_iter = mMeshes.find(info->mReferenceMeshName); +			if (polymesh_iter != mMeshes.end())  			{ -				poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, iter->second); +				poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second);  				poly_mesh->setAvatar(this);  			}  			else  			{  				// This should never happen +				LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL;  			}  		}  		else @@ -5864,14 +5479,13 @@ BOOL LLVOAvatar::loadMeshNodes()  		mMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));  		mesh->setMesh( poly_mesh ); -  		mesh->setLOD( info->mMinPixelArea ); -		LLVOAvatarInfo::LLVOAvatarMeshInfo::morph_info_list_t::iterator iter; -		for (iter = info->mPolyMorphTargetInfoList.begin(); -			 iter != info->mPolyMorphTargetInfoList.end(); iter++) +		for (LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin(); +			 xmlinfo_iter != info->mPolyMorphTargetInfoList.end();  +			 xmlinfo_iter++)  		{ -			LLVOAvatarInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*iter); +			const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter);  			LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());  			if (!param->setInfo(info_pair->first))  			{ @@ -5961,7 +5575,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)  	// We always want to look good to ourselves  	if( mIsSelf )  	{ -		mPixelArea = llmax( mPixelArea, F32(LOCTEX_IMAGE_SIZE_SELF / 16) ); +		mPixelArea = llmax( mPixelArea, F32(TEX_IMAGE_SIZE_SELF / 16) );  	}  } @@ -6078,7 +5692,7 @@ void LLVOAvatar::updateShadowFaces()  	//  	// render avatar shadows  	// -	if (mInAir || mUpdatePeriod >= VOAVATAR_IMPOSTOR_PERIOD) +	if (mInAir || mUpdatePeriod >= IMPOSTOR_PERIOD)  	{  		face0p->setSize(0, 0);  		face1p->setSize(0, 0); @@ -6173,9 +5787,9 @@ void LLVOAvatar::updateShadowFaces()  //-----------------------------------------------------------------------------  void LLVOAvatar::updateSexDependentLayerSets( BOOL set_by_user )  { -	invalidateComposite( mHeadLayerSet,			set_by_user ); -	invalidateComposite( mLowerBodyLayerSet,	set_by_user ); -	invalidateComposite( mUpperBodyLayerSet,	set_by_user ); +	invalidateComposite( mBakedTextureData[BAKED_HEAD].mTexLayerSet,  set_by_user ); +	invalidateComposite( mBakedTextureData[BAKED_UPPER].mTexLayerSet,	set_by_user ); +	invalidateComposite( mBakedTextureData[BAKED_LOWER].mTexLayerSet,	set_by_user );  	updateMeshTextures();  } @@ -6188,74 +5802,32 @@ void LLVOAvatar::dirtyMesh()  }  //----------------------------------------------------------------------------- -// requestLayerSetUpdate() +// hideSkirt()  //----------------------------------------------------------------------------- -void LLVOAvatar::requestLayerSetUpdate( LLVOAvatar::ELocTexIndex i ) +void LLVOAvatar::hideSkirt()  { -	switch( i ) -	{ -	case LOCTEX_HEAD_BODYPAINT: -		if( mHeadLayerSet ) -		{ -			mHeadLayerSet->requestUpdate(); -		} -		break; - -	case LOCTEX_UPPER_BODYPAINT:   -	case LOCTEX_UPPER_SHIRT: -	case LOCTEX_UPPER_GLOVES: -	case LOCTEX_UPPER_UNDERSHIRT: -		if( mUpperBodyLayerSet ) -		{ -			mUpperBodyLayerSet->requestUpdate(); -		} -		break; - -	case LOCTEX_LOWER_BODYPAINT:   -	case LOCTEX_LOWER_PANTS: -	case LOCTEX_LOWER_SHOES: -	case LOCTEX_LOWER_SOCKS: -	case LOCTEX_LOWER_UNDERPANTS: -		if( mLowerBodyLayerSet ) -		{ -			mLowerBodyLayerSet->requestUpdate(); -		} -		break; - -	case LOCTEX_EYES_IRIS: -		if( mEyesLayerSet ) -		{ -			mEyesLayerSet->requestUpdate(); -		} -		break; - - -	case LOCTEX_SKIRT: -		if( mSkirtLayerSet ) -		{ -			mSkirtLayerSet->requestUpdate(); -		} -		break; - - -	case LOCTEX_UPPER_JACKET: -	case LOCTEX_LOWER_JACKET: -		if( mUpperBodyLayerSet ) -		{ -			mUpperBodyLayerSet->requestUpdate(); -		} +	mMeshLOD[MESH_ID_SKIRT]->setVisible(FALSE, TRUE); +} -		if( mLowerBodyLayerSet ) -		{ -			mLowerBodyLayerSet->requestUpdate(); -		} -		break; -	case LOCTEX_NUM_ENTRIES: -		llerrs << "Bogus texture value " << i << llendl; -		break; +//----------------------------------------------------------------------------- +// requestLayerSetUpdate() +//----------------------------------------------------------------------------- +void LLVOAvatar::requestLayerSetUpdate(ETextureIndex index ) +{ +	/* switch(index) +		case LOCTEX_UPPER_BODYPAINT:   +		case LOCTEX_UPPER_SHIRT: +			if( mUpperBodyLayerSet ) +				mUpperBodyLayerSet->requestUpdate(); */ +	const LLVOAvatarDictionary::TextureDictionaryEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); +	if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) +		return; +	const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; +	if (mBakedTextureData[baked_index].mTexLayerSet) +	{ +		mBakedTextureData[baked_index].mTexLayerSet->requestUpdate();  	} -  }  void LLVOAvatar::setParent(LLViewerObject* parent) @@ -6616,6 +6188,7 @@ const std::string LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id)  // static   // onLocalTextureLoaded()  //----------------------------------------------------------------------------- +  void LLVOAvatar::onLocalTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )  {  	//llinfos << "onLocalTextureLoaded: " << src_vi->getID() << llendl; @@ -6625,37 +6198,47 @@ void LLVOAvatar::onLocalTextureLoaded( BOOL success, LLViewerImage *src_vi, LLIm  	if (success)  	{  		LLVOAvatar *self = (LLVOAvatar *)gObjectList.findObject(data->mAvatarID); -		LLVOAvatar::ELocTexIndex idx = data->mIndex; -		if( self && -			(!self->mLocalTextureBaked[ idx ]) && -			(self->mLocalTexture[ idx ].notNull()) && -			(self->mLocalTexture[ idx ]->getID() == src_id) && -			(discard_level < self->mLocalTextureDiscard[idx])) -		{ -			self->mLocalTextureDiscard[idx] = discard_level; -			self->requestLayerSetUpdate( idx ); -			if( self->mIsSelf && gAgent.cameraCustomizeAvatar() ) -			{ -				LLVisualParamHint::requestHintUpdates(); +		if (self) +		{ +			ETextureIndex index = data->mIndex; +			if (!self->isIndexLocalTexture(index)) return; +			LocalTextureData &local_tex_data = self->mLocalTextureData[index]; +			if(!local_tex_data.mIsBakedReady && +			   local_tex_data.mImage.notNull() && +			   (local_tex_data.mImage->getID() == src_id) && +			   discard_level < local_tex_data.mDiscard) +			{ +				local_tex_data.mDiscard = discard_level; +				if ( self->isSelf() && !gAgent.cameraCustomizeAvatar() ) +				{ +					self->requestLayerSetUpdate( index ); +				} +				else if( self->isSelf() && gAgent.cameraCustomizeAvatar() ) +				{ +					LLVisualParamHint::requestHintUpdates(); +				} +				self->updateMeshTextures();  			} -			self->updateMeshTextures();  		}  	}  	else if (final)  	{  		LLVOAvatar *self = (LLVOAvatar *)gObjectList.findObject(data->mAvatarID); -		LLVOAvatar::ELocTexIndex idx = data->mIndex; -		// Failed: asset is missing -		if( self && -			(!self->mLocalTextureBaked[ idx ]) && -			(self->mLocalTexture[ idx ].notNull()) && -			(self->mLocalTexture[ idx ]->getID() == src_id)) +		if (self)  		{ -			self->mLocalTextureDiscard[idx] = 0; // we check that it's missing later -			self->requestLayerSetUpdate( idx ); -			self->updateMeshTextures(); +			ETextureIndex index = data->mIndex; +			if (!self->isIndexLocalTexture(index)) return; +			LocalTextureData &local_tex_data = self->mLocalTextureData[index]; +			// Failed: asset is missing +			if(!local_tex_data.mIsBakedReady && +			   local_tex_data.mImage.notNull() && +			   local_tex_data.mImage->getID() == src_id) +			{ +				local_tex_data.mDiscard = 0; +				self->requestLayerSetUpdate( index ); +				self->updateMeshTextures(); +			}  		} -		  	}  	if( final || !success ) @@ -6666,29 +6249,13 @@ void LLVOAvatar::onLocalTextureLoaded( BOOL success, LLViewerImage *src_vi, LLIm  void LLVOAvatar::updateComposites()  { -	if( mHeadLayerSet ) -	{ -		mHeadLayerSet->updateComposite(); -	} - -	if( mUpperBodyLayerSet ) -	{ -		mUpperBodyLayerSet->updateComposite(); -	} - -	if( mLowerBodyLayerSet ) -	{ -		mLowerBodyLayerSet->updateComposite(); -	} - -	if( mEyesLayerSet ) -	{ -		mEyesLayerSet->updateComposite(); -	} - -	if( mSkirtLayerSet && isWearingWearableType( WT_SKIRT )) +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		mSkirtLayerSet->updateComposite(); +		if ( mBakedTextureData[i].mTexLayerSet  +			&& ((i != BAKED_SKIRT) || isWearingWearableType( WT_SKIRT )) ) +		{ +			mBakedTextureData[i].mTexLayerSet->updateComposite(); +		}  	}  } @@ -6740,6 +6307,10 @@ void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user  	{  		layer_name = "eyes";  	} +	else if (layerset == mHairLayerSet) +	{ +		layer_name = "hair"; +	}  	else if (layerset == mSkirtLayerSet)  	{  		layer_name = "skirt"; @@ -6758,47 +6329,52 @@ void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user  		llassert( mIsSelf );  		ETextureIndex baked_te = getBakedTE( layerset ); -		if( gAgent.cameraCustomizeAvatar() ) -		{ -			mSavedTE[ baked_te ].setNull();   -		} -		else -		{ -			setTEImage( baked_te, gImageList.getImage(IMG_DEFAULT_AVATAR) ); -			layerset->requestUpload(); -		} +		setTEImage( baked_te, gImageList.getImage(IMG_DEFAULT_AVATAR) ); +		layerset->requestUpload();  	}  } +void LLVOAvatar::invalidateAll() +{ +	for (U32 i = 0; i < mBakedTextureData.size(); i++) +	{ +		invalidateComposite(mBakedTextureData[i].mTexLayerSet, TRUE); +	} +	updateMeshTextures(); +}  void LLVOAvatar::onGlobalColorChanged( LLTexGlobalColor* global_color, BOOL set_by_user )  {  	if( global_color == mTexSkinColor )  	{  //		llinfos << "invalidateComposite cause: onGlobalColorChanged( skin color )" << llendl;  -		invalidateComposite( mHeadLayerSet,			set_by_user ); -		invalidateComposite( mUpperBodyLayerSet,	set_by_user ); -		invalidateComposite( mLowerBodyLayerSet,	set_by_user ); +		invalidateComposite( mBakedTextureData[BAKED_HEAD].mTexLayerSet,  set_by_user ); +		invalidateComposite( mBakedTextureData[BAKED_UPPER].mTexLayerSet,	set_by_user ); +		invalidateComposite( mBakedTextureData[BAKED_LOWER].mTexLayerSet,	set_by_user );  	}  	else  	if( global_color == mTexHairColor )  	{  //		llinfos << "invalidateComposite cause: onGlobalColorChanged( hair color )" << llendl;  -		invalidateComposite( mHeadLayerSet, set_by_user ); - -		LLColor4 color = mTexHairColor->getColor(); -		mHairMesh0.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh1.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh2.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh3.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh4.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh5.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); +		invalidateComposite( mBakedTextureData[BAKED_HEAD].mTexLayerSet,  set_by_user ); +		invalidateComposite( mBakedTextureData[BAKED_HAIR].mTexLayerSet,  set_by_user ); +		 +		// ! BACKWARDS COMPATIBILITY ! +		// Fix for dealing with avatars from viewers that don't bake hair. +		if (!isTextureDefined(mBakedTextureData[BAKED_HAIR].mTextureIndex)) +		{ +			LLColor4 color = mTexHairColor->getColor(); +			for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++) +			{ +				mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); +			} +		}  	}  	else  	if( global_color == mTexEyeColor )  	{  //		llinfos << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << llendl;  -		invalidateComposite( mEyesLayerSet, set_by_user ); +		invalidateComposite( mBakedTextureData[BAKED_EYES].mTexLayerSet,  set_by_user );  	}  	updateMeshTextures();  } @@ -6807,9 +6383,9 @@ void LLVOAvatar::forceBakeAllTextures(bool slam_for_debug)  {  	llinfos << "TAT: forced full rebake. " << llendl; -	for (S32 i = 0; i < BAKED_TEXTURE_COUNT; i++) +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		ETextureIndex baked_index = sBakedTextureIndices[i]; +		ETextureIndex baked_index = mBakedTextureData[i].mTextureIndex;  		LLTexLayerSet* layer_set = getLayerSet(baked_index);  		if (layer_set)  		{ @@ -6846,20 +6422,30 @@ void LLVOAvatar::processRebakeAvatarTextures(LLMessageSystem* msg, void**)  	// If this is a texture corresponding to one of our baked entries,   	// just rebake that layer set.  	BOOL found = FALSE; -	for (S32 i = 0; i < BAKED_TEXTURE_COUNT; i++) + +	/* ETextureIndex baked_texture_indices[BAKED_NUM_INDICES] = +			TEX_HEAD_BAKED, +			TEX_UPPER_BAKED, */ +	for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); +		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); +		 iter++)  	{ -		ETextureIndex baked_index = sBakedTextureIndices[i]; -		if (texture_id == self->getTEImage(baked_index)->getID()) +		const ETextureIndex index = iter->first; +		const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second; +		if (text_dict->mIsBakedTexture)  		{ -			LLTexLayerSet* layer_set = self->getLayerSet(baked_index); -			if (layer_set) +			if (texture_id == self->getTEImage(index)->getID())  			{ -				llinfos << "TAT: rebake - matched entry " << (S32)baked_index << llendl; -				// Apparently set_by_user == force upload -				BOOL set_by_user = TRUE; -				self->invalidateComposite(layer_set, set_by_user); -				found = TRUE; -				LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); +				LLTexLayerSet* layer_set = self->getLayerSet(index); +				if (layer_set) +				{ +					llinfos << "TAT: rebake - matched entry " << (S32)index << llendl; +					// Apparently set_by_user == force upload +					BOOL set_by_user = TRUE; +					self->invalidateComposite(layer_set, set_by_user); +					found = TRUE; +					LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); +				}  			}  		}  	} @@ -6877,48 +6463,48 @@ void LLVOAvatar::processRebakeAvatarTextures(LLMessageSystem* msg, void**)  } -BOOL LLVOAvatar::getLocalTextureRaw(S32 index, LLImageRaw* image_raw) +BOOL LLVOAvatar::getLocalTextureRaw(ETextureIndex index, LLImageRaw* image_raw)  { +	if (!isIndexLocalTexture(index)) return FALSE; +      BOOL success = FALSE; -	if( (0 <= index) && (index < LOCTEX_NUM_ENTRIES) ) +	if (getLocalTextureID(index) == IMG_DEFAULT_AVATAR)  	{ -		if (mLocalTexture[ index ].isNull() || mLocalTexture[ index ]->getID() == IMG_DEFAULT_AVATAR ) +		success = TRUE; +	} +	else +	{ +		LocalTextureData &local_tex_data = mLocalTextureData[index]; +		if(local_tex_data.mImage->readBackRaw(-1, image_raw, false))  		{  			success = TRUE;  		}  		else  		{ -			if( mLocalTexture[ index ]->readBackRaw(-1, image_raw, false) ) -			{ -				success = TRUE; -			} -			else -			{ -				// No data loaded yet -				setLocalTexture( (ELocTexIndex)index, getTEImage( index ), FALSE ); -			} +			// No data loaded yet +			setLocalTexture( (ETextureIndex)index, getTEImage( index ), FALSE );  		}  	}  	return success;  } -BOOL LLVOAvatar::getLocalTextureGL(S32 index, LLImageGL** image_gl_pp) +BOOL LLVOAvatar::getLocalTextureGL(ETextureIndex index, LLImageGL** image_gl_pp)  { +	if (!isIndexLocalTexture(index)) return FALSE; +  	BOOL success = FALSE;  	*image_gl_pp = NULL; -	if( (0 <= index) && (index < LOCTEX_NUM_ENTRIES) ) +	if (getLocalTextureID(index) == IMG_DEFAULT_AVATAR)  	{ -		if( mLocalTexture[ index ].isNull() || mLocalTexture[ index ]->getID() == IMG_DEFAULT_AVATAR) -		{ -			success = TRUE; -		} -		else -		{ -			*image_gl_pp = mLocalTexture[ index ]; -			success = TRUE; -		} +		success = TRUE; +	} +	else +	{ +		LocalTextureData &local_tex_data = mLocalTextureData[index]; +		*image_gl_pp = local_tex_data.mImage; +		success = TRUE;  	}  	if( !success ) @@ -6928,11 +6514,13 @@ BOOL LLVOAvatar::getLocalTextureGL(S32 index, LLImageGL** image_gl_pp)  	return success;  } -const LLUUID& LLVOAvatar::getLocalTextureID( S32 index ) +const LLUUID& LLVOAvatar::getLocalTextureID(ETextureIndex index)  { -	if (index >= 0 && mLocalTexture[index].notNull()) +	if (!isIndexLocalTexture(index)) return IMG_DEFAULT_AVATAR; +	 +	if (mLocalTextureData[index].mImage.notNull())  	{ -		return mLocalTexture[index]->getID(); +		return mLocalTextureData[index].mImage->getID();  	}  	else  	{ @@ -6977,8 +6565,15 @@ BOOL LLVOAvatar::updateIsFullyLoaded()  		loading = TRUE;  	} -	// are our texture settings still default? -	if ((getTEImage( TEX_HAIR )->getID() == IMG_DEFAULT)) +	//  +	if (mIsSelf) +	{ +		if (!isTextureDefined(TEX_HAIR)) +		{ +			loading = TRUE; +		} +	} +	else if (!isTextureDefined(TEX_LOWER_BAKED) || !isTextureDefined(TEX_UPPER_BAKED) || !isTextureDefined(TEX_HEAD_BAKED))  	{  		loading = TRUE;  	} @@ -6998,14 +6593,14 @@ BOOL LLVOAvatar::updateIsFullyLoaded()  	// texture info for our shirt/pants, stay unloaded:  	if (!mPreviousFullyLoaded)  	{ -		if ((!isLocalTextureDataAvailable(mLowerBodyLayerSet)) && -			(getTEImage(TEX_LOWER_BAKED)->getID() == IMG_DEFAULT_AVATAR)) +		if ((!isLocalTextureDataAvailable(mBakedTextureData[BAKED_LOWER].mTexLayerSet)) && +			(!isTextureDefined(TEX_LOWER_BAKED)))  		{  			loading = TRUE;  		} -		if ((!isLocalTextureDataAvailable(mUpperBodyLayerSet)) && -			(getTEImage(TEX_UPPER_BAKED)->getID() == IMG_DEFAULT_AVATAR)) +		if ((!isLocalTextureDataAvailable(mBakedTextureData[BAKED_UPPER].mTexLayerSet)) && +			(!isTextureDefined(TEX_UPPER_BAKED)))  		{  			loading = TRUE;  		} @@ -7057,9 +6652,10 @@ LLMotion*		LLVOAvatar::findMotion(const LLUUID& id)  void LLVOAvatar::getLocalTextureByteCount( S32* gl_bytes )  {  	*gl_bytes = 0; -	for( S32 i = 0; i < LOCTEX_NUM_ENTRIES; i++ ) +	for( S32 i = 0; i < TEX_NUM_INDICES; i++ )  	{ -		LLViewerImage* image_gl = mLocalTexture[i]; +		if (!isIndexLocalTexture((ETextureIndex)i)) continue; +		LLViewerImage* image_gl = mLocalTextureData[(ETextureIndex)i].mImage;  		if( image_gl )  		{  			S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); @@ -7122,7 +6718,7 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes )  	default:	llassert(0);	components = 4; internal_format = GL_RGBA8;				break;  	} -	*texture_bytes = components * VOAVATAR_SCRATCH_TEX_WIDTH * VOAVATAR_SCRATCH_TEX_HEIGHT; +	*texture_bytes = components * SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT;  	if( LLVOAvatar::sScratchTexNames.checkData( format ) )  	{ @@ -7142,7 +6738,7 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes )  		LLImageGL::setManualImage(  			GL_TEXTURE_2D, 0, internal_format,  -			VOAVATAR_SCRATCH_TEX_WIDTH, VOAVATAR_SCRATCH_TEX_HEIGHT, +			SCRATCH_TEX_WIDTH, SCRATCH_TEX_HEIGHT,  			format, GL_UNSIGNED_BYTE, NULL );  		stop_glerror(); @@ -7174,7 +6770,7 @@ void LLVOAvatar::setLocTexTE( U8 te, LLViewerImage* image, BOOL set_by_user )  		return;  	} -	if( te >= TEX_NUM_ENTRIES ) +	if( te >= TEX_NUM_INDICES )  	{  		llassert(0);  		return; @@ -7185,7 +6781,7 @@ void LLVOAvatar::setLocTexTE( U8 te, LLViewerImage* image, BOOL set_by_user )  		return;  	} -	if (isTextureIndexBaked(te)) +	if (isIndexBakedTexture((ETextureIndex)te))  	{  		llassert(0);  		return; @@ -7208,32 +6804,13 @@ void LLVOAvatar::setLocTexTE( U8 te, LLViewerImage* image, BOOL set_by_user )  void LLVOAvatar::setupComposites()  { -	// Don't invalidate the baked textures we had on start-up. -	BOOL head_baked =  ( getTEImage( TEX_HEAD_BAKED  )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL eyes_baked =  ( getTEImage( TEX_EYES_BAKED  )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	 -	if (mHeadLayerSet) -	{ -		mHeadLayerSet->setUpdatesEnabled(		!head_baked  ); -	} -	if (mUpperBodyLayerSet) -	{ -		mUpperBodyLayerSet->setUpdatesEnabled(	!upper_baked ); -	} -	if (mLowerBodyLayerSet) -	{ -		mLowerBodyLayerSet->setUpdatesEnabled(	!lower_baked ); -	} -	if (mEyesLayerSet) -	{ -		mEyesLayerSet->setUpdatesEnabled(		!eyes_baked  ); -	} -	if (mSkirtLayerSet) +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		mSkirtLayerSet->setUpdatesEnabled(		!skirt_baked  ); +		bool layer_baked = isTextureDefined(mBakedTextureData[i].mTextureIndex); +		if (mBakedTextureData[i].mTexLayerSet) +		{ +			mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( !layer_baked ); +		}  	}  } @@ -7243,447 +6820,193 @@ void LLVOAvatar::setupComposites()  //-----------------------------------------------------------------------------  void LLVOAvatar::updateMeshTextures()  { -//	llinfos << "updateMeshTextures" << llendl; -	if (gNoRender) -	{ -		return; -	} +    // llinfos << "updateMeshTextures" << llendl; +	if (gNoRender) return; +  	// if user has never specified a texture, assign the default -	LLViewerImage* default_tex = gImageList.getImage(IMG_DEFAULT); -	U8 num_TEs = getNumTEs(); -	for (U32 i=0; i<num_TEs; i++) +	for (U32 i=0; i < getNumTEs(); i++)  	{ -		LLViewerImage* te_image = getTEImage(i); -		if( (NULL == te_image) || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT) ) +		const LLViewerImage* te_image = getTEImage(i); +		if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT))  		{ -			if( TEX_HAIR == i ) -			{ -				setTEImage(i, default_tex ); -			} -			else -			{ -				setTEImage(i, gImageList.getImage(IMG_DEFAULT_AVATAR)); // a special texture that's never rendered. -			} +			setTEImage(i, gImageList.getImage(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR)); // IMG_DEFAULT_AVATAR = a special texture that's never rendered.  		}  	} -	// During face edit mode, we don't use baked textures -	BOOL self_customize = mIsSelf && gAgent.cameraCustomizeAvatar(); - -	BOOL head_baked = (getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL upper_baked = (getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL lower_baked = (getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL eyes_baked = (getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL skirt_baked = (getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); - -	// Nothing should be baked if we're in customize avatar mode. -	llassert( !( self_customize &&  -		( head_baked || upper_baked || lower_baked || eyes_baked ) ) ); - -	BOOL use_lkg_head_baked =  FALSE; -	BOOL use_lkg_upper_baked = FALSE; -	BOOL use_lkg_lower_baked = FALSE; -	BOOL use_lkg_eyes_baked =  FALSE; -	BOOL use_lkg_skirt_baked =  FALSE; - -	BOOL other_culled = !mIsSelf && mCulled; -	if( other_culled ) -	{ -		use_lkg_head_baked =  !head_baked  && (mLastHeadBakedID != IMG_DEFAULT_AVATAR); -		use_lkg_upper_baked = !upper_baked && (mLastUpperBodyBakedID != IMG_DEFAULT_AVATAR); -		use_lkg_lower_baked = !lower_baked && (mLastLowerBodyBakedID != IMG_DEFAULT_AVATAR); -		use_lkg_eyes_baked =  !eyes_baked  && (mLastEyesBakedID != IMG_DEFAULT_AVATAR); -		use_lkg_skirt_baked = !skirt_baked && (mLastSkirtBakedID != IMG_DEFAULT_AVATAR); - -		if( mHeadLayerSet ) -		{ -			mHeadLayerSet->destroyComposite(); -		} - -		if( mUpperBodyLayerSet ) -		{ -			mUpperBodyLayerSet->destroyComposite(); -		} - -		if( mLowerBodyLayerSet ) -		{ -			mLowerBodyLayerSet->destroyComposite(); -		} +	const BOOL self_customizing = mIsSelf && gAgent.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures +	const BOOL other_culled = !mIsSelf && mCulled; -		if( mEyesLayerSet ) -		{ -			mEyesLayerSet->destroyComposite(); -		} +	std::vector<bool> is_layer_baked; +	is_layer_baked.resize(mBakedTextureData.size(), false); -		if( mSkirtLayerSet ) -		{ -			mSkirtLayerSet->destroyComposite(); -		} +	std::vector<bool> use_lkg_baked_layer; // lkg = "last known good" +	use_lkg_baked_layer.resize(mBakedTextureData.size(), false); -	} -	else -	if( !self_customize ) +	for (U32 i=0; i < mBakedTextureData.size(); i++)  	{ -		// When you're changing clothes and you're not in Appearance mode, -		// use the last-known good baked texture until you finish the first -		// render of the new layerset. -		use_lkg_head_baked =  !head_baked  && (mLastHeadBakedID      != IMG_DEFAULT_AVATAR) && mHeadLayerSet      && !mHeadLayerSet->getComposite()->isInitialized(); -		use_lkg_upper_baked = !upper_baked && (mLastUpperBodyBakedID != IMG_DEFAULT_AVATAR) && mUpperBodyLayerSet && !mUpperBodyLayerSet->getComposite()->isInitialized(); -		use_lkg_lower_baked = !lower_baked && (mLastLowerBodyBakedID != IMG_DEFAULT_AVATAR) && mLowerBodyLayerSet && !mLowerBodyLayerSet->getComposite()->isInitialized(); -		use_lkg_eyes_baked =  !eyes_baked  && (mLastEyesBakedID      != IMG_DEFAULT_AVATAR) && mEyesLayerSet      && !mEyesLayerSet->getComposite()->isInitialized(); -		use_lkg_skirt_baked = !skirt_baked && (mLastSkirtBakedID     != IMG_DEFAULT_AVATAR) && mSkirtLayerSet     && !mSkirtLayerSet->getComposite()->isInitialized(); - -		if( use_lkg_head_baked )  -		{ -			mHeadLayerSet->setUpdatesEnabled( TRUE ); -		} +		is_layer_baked[i] = isTextureDefined(mBakedTextureData[i].mTextureIndex); -		if( use_lkg_upper_baked )  +		if (!other_culled)  		{ -			mUpperBodyLayerSet->setUpdatesEnabled( TRUE ); -		} - -		if( use_lkg_lower_baked ) -		{ -			mLowerBodyLayerSet->setUpdatesEnabled( TRUE ); +			// When an avatar is changing clothes and not in Appearance mode, +			// use the last-known good baked texture until it finish the first +			// render of the new layerset. +			use_lkg_baked_layer[i] = (!is_layer_baked[i]  +									  && (mBakedTextureData[i].mLastTextureIndex != IMG_DEFAULT_AVATAR)  +									  && mBakedTextureData[i].mTexLayerSet  +									  && !mBakedTextureData[i].mTexLayerSet->getComposite()->isInitialized()); +			if (use_lkg_baked_layer[i]) +			{ +				mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled(TRUE); +			}  		} - -		if( use_lkg_eyes_baked )   +		else  		{ -			mEyesLayerSet->setUpdatesEnabled( TRUE ); +			use_lkg_baked_layer[i] = (!is_layer_baked[i]  +									  && mBakedTextureData[i].mLastTextureIndex != IMG_DEFAULT_AVATAR); +			if (mBakedTextureData[i].mTexLayerSet) +			{ +				mBakedTextureData[i].mTexLayerSet->destroyComposite(); +			}  		} -		if( use_lkg_skirt_baked )   -		{ -			mSkirtLayerSet->setUpdatesEnabled( TRUE ); -		}  	}  	// Baked textures should be requested from the sim this avatar is on. JC -	LLHost target_host = getObjectHost(); +	const LLHost target_host = getObjectHost();  	if (!target_host.isOk())  	{  		llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl;  	} -		 -	// Head -	if( use_lkg_head_baked ) -	{ -		LLViewerImage* baked = gImageList.getImageFromHost( mLastHeadBakedID, target_host ); -		mHeadMesh0.setTexture( baked ); -		mHeadMesh1.setTexture( baked ); -		mHeadMesh2.setTexture( baked ); -		mHeadMesh3.setTexture( baked ); -		mHeadMesh4.setTexture( baked ); -		mEyeLashMesh0.setTexture( baked ); -	} -	else -	if( !self_customize && head_baked ) -	{ -		LLViewerImage* baked = getTEImage( TEX_HEAD_BAKED ); -		if( baked->getID() == mLastHeadBakedID ) -		{ -			// Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). -			useBakedTexture( baked->getID() ); -		} -		else -		{ -			mHeadBakedLoaded = FALSE; -			mHeadMaskDiscard = -1; -			baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));	 -			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) ); -		} -	} -	else -	if( mHeadLayerSet && !other_culled ) -	{ -		mHeadLayerSet->createComposite(); -		mHeadLayerSet->setUpdatesEnabled( TRUE ); -		mHeadMesh0.setLayerSet( mHeadLayerSet ); -		mHeadMesh1.setLayerSet( mHeadLayerSet ); -		mHeadMesh2.setLayerSet( mHeadLayerSet ); -		mHeadMesh3.setLayerSet( mHeadLayerSet ); -		mHeadMesh4.setLayerSet( mHeadLayerSet ); -		mEyeLashMesh0.setLayerSet( mHeadLayerSet ); -	} -	else -	{ -		mHeadMesh0.setTexture( default_tex ); -		mHeadMesh1.setTexture( default_tex ); -		mHeadMesh2.setTexture( default_tex ); -		mHeadMesh3.setTexture( default_tex ); -		mHeadMesh4.setTexture( default_tex ); -		mEyeLashMesh0.setTexture( default_tex ); -	} -	// Upper body -	if( use_lkg_upper_baked ) -	{ -		LLViewerImage* baked = gImageList.getImageFromHost( mLastUpperBodyBakedID, target_host ); -		mUpperBodyMesh0.setTexture( baked ); -		mUpperBodyMesh1.setTexture( baked ); -		mUpperBodyMesh2.setTexture( baked ); -		mUpperBodyMesh3.setTexture( baked ); -		mUpperBodyMesh4.setTexture( baked ); -	} -	else -	if( !self_customize && upper_baked ) +	for (U32 i=0; i < mBakedTextureData.size(); i++)  	{ -		LLViewerImage* baked = getTEImage( TEX_UPPER_BAKED ); - -		if( baked->getID() == mLastUpperBodyBakedID ) +		if (use_lkg_baked_layer[i])  		{ -			// Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). -			useBakedTexture( baked->getID() ); -		} -		else -		{ -			mUpperBakedLoaded = FALSE; -			mUpperMaskDiscard = -1; -			baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID )); -			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) ); +			LLViewerImage* baked_img = gImageList.getImageFromHost( mBakedTextureData[i].mLastTextureIndex, target_host ); +			for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) +			{ +				mBakedTextureData[i].mMeshes[k]->setTexture( baked_img ); +			}  		} -	} -	else -	if( mUpperBodyLayerSet && !other_culled ) -	{ -		mUpperBodyLayerSet->createComposite(); -		mUpperBodyLayerSet->setUpdatesEnabled( TRUE ); -		mUpperBodyMesh0.setLayerSet( mUpperBodyLayerSet ); -		mUpperBodyMesh1.setLayerSet( mUpperBodyLayerSet ); -		mUpperBodyMesh2.setLayerSet( mUpperBodyLayerSet ); -		mUpperBodyMesh3.setLayerSet( mUpperBodyLayerSet ); -		mUpperBodyMesh4.setLayerSet( mUpperBodyLayerSet ); -	} -	else -	{ -		mUpperBodyMesh0.setTexture( default_tex ); -		mUpperBodyMesh1.setTexture(	default_tex ); -		mUpperBodyMesh2.setTexture(	default_tex ); -		mUpperBodyMesh3.setTexture(	default_tex ); -		mUpperBodyMesh4.setTexture(	default_tex ); -	} - -	// Lower body -	if( use_lkg_lower_baked ) -	{ -		LLViewerImage* baked = gImageList.getImageFromHost( mLastLowerBodyBakedID, target_host ); -		mLowerBodyMesh0.setTexture( baked ); -		mLowerBodyMesh1.setTexture( baked ); -		mLowerBodyMesh2.setTexture( baked ); -		mLowerBodyMesh3.setTexture( baked ); -		mLowerBodyMesh4.setTexture( baked ); -	} -	else -	if( !self_customize && lower_baked ) -	{ -		LLViewerImage* baked = getTEImage( TEX_LOWER_BAKED ); -		if( baked->getID() == mLastLowerBodyBakedID ) +		else if (!self_customizing && is_layer_baked[i])  		{ -			// Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). -			useBakedTexture( baked->getID() ); +			LLViewerImage* baked_img = getTEImage( mBakedTextureData[i].mTextureIndex ); +			if( baked_img->getID() == mBakedTextureData[i].mLastTextureIndex ) +			{ +				// Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). +				useBakedTexture( baked_img->getID() ); +			} +			else +			{ +				mBakedTextureData[i].mIsLoaded = FALSE; +				if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) ) +				{ +					baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));	 +				} +				baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) ); +			}  		} -		else +		else if (mBakedTextureData[i].mTexLayerSet  +				 && !other_culled  +				 && (i != BAKED_HAIR || is_layer_baked[i] || mIsSelf)) // ! BACKWARDS COMPATIBILITY ! workaround for old viewers.  		{ -			mLowerBakedLoaded = FALSE; -			mLowerMaskDiscard = -1; -			baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID )); -			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) ); +			mBakedTextureData[i].mTexLayerSet->createComposite(); +			mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( TRUE ); +			for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) +			{ +				mBakedTextureData[i].mMeshes[k]->setLayerSet( mBakedTextureData[i].mTexLayerSet ); +			}  		}  	} -	else -	if( mLowerBodyLayerSet && !other_culled ) -	{ -		mLowerBodyLayerSet->createComposite(); -		mLowerBodyLayerSet->setUpdatesEnabled( TRUE ); -		mLowerBodyMesh0.setLayerSet( mLowerBodyLayerSet ); -		mLowerBodyMesh1.setLayerSet( mLowerBodyLayerSet ); -		mLowerBodyMesh2.setLayerSet( mLowerBodyLayerSet ); -		mLowerBodyMesh3.setLayerSet( mLowerBodyLayerSet ); -		mLowerBodyMesh4.setLayerSet( mLowerBodyLayerSet ); -	} -	else -	{ -		mLowerBodyMesh0.setTexture(	default_tex ); -		mLowerBodyMesh1.setTexture(	default_tex ); -		mLowerBodyMesh2.setTexture(	default_tex ); -		mLowerBodyMesh3.setTexture(	default_tex ); -		mLowerBodyMesh4.setTexture(	default_tex ); -	} - -	// Eyes -	if( use_lkg_eyes_baked ) -	{ -		LLViewerImage* baked = gImageList.getImageFromHost( mLastEyesBakedID, target_host ); -		mEyeBallLeftMesh0.setTexture(  baked ); -		mEyeBallLeftMesh1.setTexture(  baked ); -		mEyeBallRightMesh0.setTexture( baked ); -		mEyeBallRightMesh1.setTexture( baked ); -	} -	else -	if( !self_customize && eyes_baked ) +	 +	// ! BACKWARDS COMPATIBILITY ! +	// Workaround for viewing avatars from old viewers that haven't baked hair textures. +	// if (!isTextureDefined(mBakedTextureData[BAKED_HAIR].mTextureIndex)) +	if (!is_layer_baked[BAKED_HAIR])  	{ -		LLViewerImage* baked = getTEImage( TEX_EYES_BAKED ); -		if( baked->getID() == mLastEyesBakedID ) -		{ -			// Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). -			useBakedTexture( baked->getID() ); -		} -		else +		const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1); +		LLViewerImage* hair_img = getTEImage( TEX_HAIR ); +		for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++)  		{ -			mEyesBakedLoaded = FALSE; -			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) ); +			mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); +			mBakedTextureData[BAKED_HAIR].mMeshes[i]->setTexture( hair_img );  		} -	} -	else -	if( mEyesLayerSet && !other_culled ) -	{ -		mEyesLayerSet->createComposite(); -		mEyesLayerSet->setUpdatesEnabled( TRUE ); -		mEyeBallLeftMesh0.setLayerSet( mEyesLayerSet ); -		mEyeBallLeftMesh1.setLayerSet( mEyesLayerSet ); -		mEyeBallRightMesh0.setLayerSet( mEyesLayerSet ); -		mEyeBallRightMesh1.setLayerSet( mEyesLayerSet ); -	} -	else +		mHasBakedHair = FALSE; +	}  +	else   	{ -		mEyeBallLeftMesh0.setTexture( default_tex ); -		mEyeBallLeftMesh1.setTexture( default_tex ); -		mEyeBallRightMesh0.setTexture( default_tex ); -		mEyeBallRightMesh1.setTexture( default_tex ); -	} - -	// Skirt -	if( use_lkg_skirt_baked ) -	{ -		LLViewerImage* baked = gImageList.getImageFromHost( mLastSkirtBakedID, target_host ); -		mSkirtMesh0.setTexture(  baked ); -		mSkirtMesh1.setTexture(  baked ); -		mSkirtMesh2.setTexture(  baked ); -		mSkirtMesh3.setTexture(  baked ); -		mSkirtMesh4.setTexture(  baked ); -	} -	else -	if( !self_customize && skirt_baked ) -	{ -		LLViewerImage* baked = getTEImage( TEX_SKIRT_BAKED ); -		if( baked->getID() == mLastSkirtBakedID ) +		for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++)  		{ -			// Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). -			useBakedTexture( baked->getID() ); +			mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f );  		} -		else +		mHasBakedHair = TRUE; +	} +	 +	/* // Head +	   BOOL head_baked_ready = (is_layer_baked[BAKED_HEAD] && mBakedTextureData[BAKED_HEAD].mIsLoaded) || other_culled; +	   setLocalTexture( TEX_HEAD_BODYPAINT, getTEImage( TEX_HEAD_BODYPAINT ), head_baked_ready ); */ +	for (LLVOAvatarDictionary::baked_map_t::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); +		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); +		 baked_iter++) +	{ +		const EBakedTextureIndex baked_index = baked_iter->first; +		const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = baked_iter->second; +		 +		for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); +			 local_tex_iter != baked_dict->mLocalTextures.end(); +			 local_tex_iter++)  		{ -			mSkirtBakedLoaded = FALSE; -			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) ); +			const ETextureIndex texture_index = *local_tex_iter; +			const BOOL is_baked_ready = (is_layer_baked[baked_index] && mBakedTextureData[baked_index].mIsLoaded) || other_culled; +			setLocalTexture(texture_index, getTEImage(texture_index), is_baked_ready );  		}  	} -	else -	if( mSkirtLayerSet && !other_culled) -	{ -		mSkirtLayerSet->createComposite(); -		mSkirtLayerSet->setUpdatesEnabled( TRUE ); -		mSkirtMesh0.setLayerSet( mSkirtLayerSet ); -		mSkirtMesh1.setLayerSet( mSkirtLayerSet ); -		mSkirtMesh2.setLayerSet( mSkirtLayerSet ); -		mSkirtMesh3.setLayerSet( mSkirtLayerSet ); -		mSkirtMesh4.setLayerSet( mSkirtLayerSet ); -	} -	else -	{ -		mSkirtMesh0.setTexture( default_tex ); -		mSkirtMesh1.setTexture( default_tex ); -		mSkirtMesh2.setTexture( default_tex ); -		mSkirtMesh3.setTexture( default_tex ); -		mSkirtMesh4.setTexture( default_tex ); -	} - -	mHairMesh0.setTexture(						getTEImage( TEX_HAIR ) ); -	mHairMesh1.setTexture(						getTEImage( TEX_HAIR ) ); -	mHairMesh2.setTexture(						getTEImage( TEX_HAIR ) ); -	mHairMesh3.setTexture(						getTEImage( TEX_HAIR ) ); -	mHairMesh4.setTexture(						getTEImage( TEX_HAIR ) ); -	mHairMesh5.setTexture(						getTEImage( TEX_HAIR ) ); - -	if( mTexHairColor ) -	{ -		LLColor4 color = mTexHairColor->getColor(); -		mHairMesh0.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh1.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh2.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh3.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh4.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -		mHairMesh5.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); -	} - -	// Head -	BOOL head_baked_ready = (head_baked && mHeadBakedLoaded) || other_culled; -	setLocalTexture( LOCTEX_HEAD_BODYPAINT,		getTEImage( TEX_HEAD_BODYPAINT ),	head_baked_ready ); - -	// Upper body -	BOOL upper_baked_ready = (upper_baked && mUpperBakedLoaded) || other_culled; -	setLocalTexture( LOCTEX_UPPER_SHIRT,		getTEImage( TEX_UPPER_SHIRT ),		upper_baked_ready ); -	setLocalTexture( LOCTEX_UPPER_BODYPAINT,	getTEImage( TEX_UPPER_BODYPAINT ),	upper_baked_ready ); -	setLocalTexture( LOCTEX_UPPER_JACKET,		getTEImage( TEX_UPPER_JACKET ),		upper_baked_ready ); -	setLocalTexture( LOCTEX_UPPER_GLOVES,		getTEImage( TEX_UPPER_GLOVES ),		upper_baked_ready ); -	setLocalTexture( LOCTEX_UPPER_UNDERSHIRT,	getTEImage( TEX_UPPER_UNDERSHIRT ),	upper_baked_ready ); - -	// Lower body -	BOOL lower_baked_ready = (lower_baked && mLowerBakedLoaded) || other_culled; -	setLocalTexture( LOCTEX_LOWER_PANTS,		getTEImage( TEX_LOWER_PANTS ),		lower_baked_ready ); -	setLocalTexture( LOCTEX_LOWER_BODYPAINT,	getTEImage( TEX_LOWER_BODYPAINT ),	lower_baked_ready ); -	setLocalTexture( LOCTEX_LOWER_SHOES,		getTEImage( TEX_LOWER_SHOES ),		lower_baked_ready ); -	setLocalTexture( LOCTEX_LOWER_SOCKS,		getTEImage( TEX_LOWER_SOCKS ),		lower_baked_ready ); -	setLocalTexture( LOCTEX_LOWER_JACKET,		getTEImage( TEX_LOWER_JACKET ),		lower_baked_ready ); -	setLocalTexture( LOCTEX_LOWER_UNDERPANTS,	getTEImage( TEX_LOWER_UNDERPANTS ),	lower_baked_ready ); - -	// Eyes -	BOOL eyes_baked_ready = (eyes_baked && mEyesBakedLoaded) || other_culled; -	setLocalTexture( LOCTEX_EYES_IRIS,			getTEImage( TEX_EYES_IRIS ),		eyes_baked_ready ); - -	// Skirt -	BOOL skirt_baked_ready = (skirt_baked && mSkirtBakedLoaded) || other_culled; -	setLocalTexture( LOCTEX_SKIRT,				getTEImage( TEX_SKIRT ),			skirt_baked_ready ); -  	removeMissingBakedTextures();  }  //-----------------------------------------------------------------------------  // setLocalTexture()  //----------------------------------------------------------------------------- -void LLVOAvatar::setLocalTexture( ELocTexIndex idx, LLViewerImage* tex, BOOL baked_version_ready ) +void LLVOAvatar::setLocalTexture( ETextureIndex index, LLViewerImage* tex, BOOL baked_version_ready )  { +	if (!isIndexLocalTexture(index)) return; +  	S32 desired_discard = mIsSelf ? 0 : 2; +	LocalTextureData &local_tex_data = mLocalTextureData[index];  	if (!baked_version_ready)  	{ -		if (tex != mLocalTexture[idx] || mLocalTextureBaked[idx]) +		if (tex != local_tex_data.mImage || local_tex_data.mIsBakedReady)  		{ -			mLocalTextureDiscard[idx] = MAX_DISCARD_LEVEL+1; +			local_tex_data.mDiscard = MAX_DISCARD_LEVEL+1;  		}  		if (tex->getID() != IMG_DEFAULT_AVATAR)  		{ -			if (mLocalTextureDiscard[idx] > desired_discard) +			if (local_tex_data.mDiscard > desired_discard)  			{  				S32 tex_discard = tex->getDiscardLevel();  				if (tex_discard >= 0 && tex_discard <= desired_discard)  				{ -					mLocalTextureDiscard[idx] = tex_discard; -					requestLayerSetUpdate( idx ); -					if( mIsSelf && gAgent.cameraCustomizeAvatar() ) +					local_tex_data.mDiscard = tex_discard; +					if( mIsSelf && !gAgent.cameraCustomizeAvatar() ) +					{ +						requestLayerSetUpdate( index ); +					} +					else if( mIsSelf && gAgent.cameraCustomizeAvatar() )  					{  						LLVisualParamHint::requestHintUpdates();  					}  				}  				else  				{ -					tex->setLoadedCallback( onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), idx) ); +					tex->setLoadedCallback( onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), index) );  				}  			}  			tex->setMinDiscardLevel(desired_discard);  		}  	} -	mLocalTextureBaked[idx] = baked_version_ready; -	mLocalTexture[idx] = tex; +	local_tex_data.mIsBakedReady = baked_version_ready; +	local_tex_data.mImage = tex;  }  //----------------------------------------------------------------------------- @@ -7691,35 +7014,13 @@ void LLVOAvatar::setLocalTexture( ELocTexIndex idx, LLViewerImage* tex, BOOL bak  //-----------------------------------------------------------------------------  void LLVOAvatar::requestLayerSetUploads()  { -	BOOL upper_baked = (getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL lower_baked = (getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL head_baked = (getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL eyes_baked = (getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -	BOOL skirt_baked = (getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); - -	if( !head_baked && mHeadLayerSet ) -	{ -		mHeadLayerSet->requestUpload(); -	} - -	if( !upper_baked && mUpperBodyLayerSet ) -	{ -		mUpperBodyLayerSet->requestUpload(); -	} - -	if( !lower_baked && mLowerBodyLayerSet ) -	{ -		mLowerBodyLayerSet->requestUpload(); -	} - -	if( !eyes_baked && mEyesLayerSet ) +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		mEyesLayerSet->requestUpload(); -	} - -	if( !skirt_baked && mSkirtLayerSet ) -	{ -		mSkirtLayerSet->requestUpload(); +		bool layer_baked = isTextureDefined(mBakedTextureData[i].mTextureIndex); +		if ( !layer_baked && mBakedTextureData[i].mTexLayerSet ) +		{ +			mBakedTextureData[i].mTexLayerSet->requestUpload(); +		}  	}  } @@ -7729,31 +7030,13 @@ void LLVOAvatar::requestLayerSetUploads()  //-----------------------------------------------------------------------------  void LLVOAvatar::setCompositeUpdatesEnabled( BOOL b )  { -	if( mHeadLayerSet ) +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		mHeadLayerSet->setUpdatesEnabled( b ); -	} -	 -	if( mUpperBodyLayerSet ) -	{ -		mUpperBodyLayerSet->setUpdatesEnabled( b ); -	} - -	if( mLowerBodyLayerSet ) -	{ -		mLowerBodyLayerSet->setUpdatesEnabled( b ); -	} - -	if( mEyesLayerSet ) -	{ -		mEyesLayerSet->setUpdatesEnabled( b ); -	} - -	if( mSkirtLayerSet ) -	{ -		mSkirtLayerSet->setUpdatesEnabled( b ); +		if (mBakedTextureData[i].mTexLayerSet ) +		{ +			mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( b ); +		}  	} -  }  void LLVOAvatar::addChat(const LLChat& chat) @@ -7785,14 +7068,16 @@ void LLVOAvatar::clearChat()  	mChats.clear();  } -S32 LLVOAvatar::getLocalDiscardLevel( S32 index ) +S32 LLVOAvatar::getLocalDiscardLevel( ETextureIndex index )  { +	if (!isIndexLocalTexture(index)) return FALSE; + +	LocalTextureData &local_tex_data = mLocalTextureData[index];  	if (index >= 0 -		&& mLocalTexture[index].notNull() -		&& (mLocalTexture[index]->getID() != IMG_DEFAULT_AVATAR) -		&& !mLocalTexture[index]->isMissingAsset()) +		&& getLocalTextureID(index) != IMG_DEFAULT_AVATAR +		&& !local_tex_data.mImage->isMissingAsset())  	{ -		return mLocalTexture[index]->getDiscardLevel(); +		return local_tex_data.mImage->getDiscardLevel();  	}  	else  	{ @@ -7803,39 +7088,27 @@ S32 LLVOAvatar::getLocalDiscardLevel( S32 index )  //-----------------------------------------------------------------------------  // isLocalTextureDataFinal() -// Returns true is the highest quality discard level exists for every texture +// Returns true if the highest quality discard level exists for every texture  // in the layerset.  //-----------------------------------------------------------------------------  BOOL LLVOAvatar::isLocalTextureDataFinal( LLTexLayerSet* layerset )  { -	if( layerset == mHeadLayerSet ) -	{ -		return getLocalDiscardLevel( LOCTEX_HEAD_BODYPAINT ) == 0; -	} -	else if( layerset == mUpperBodyLayerSet ) +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		return getLocalDiscardLevel( LOCTEX_UPPER_SHIRT ) == 0 && -			getLocalDiscardLevel( LOCTEX_UPPER_BODYPAINT ) == 0 && -			getLocalDiscardLevel( LOCTEX_UPPER_JACKET ) == 0 &&  -			getLocalDiscardLevel( LOCTEX_UPPER_GLOVES ) == 0 &&  -			getLocalDiscardLevel( LOCTEX_UPPER_UNDERSHIRT ) == 0; -	} -	else if( layerset == mLowerBodyLayerSet ) -	{ -		return getLocalDiscardLevel( LOCTEX_LOWER_PANTS ) == 0 && -			getLocalDiscardLevel( LOCTEX_LOWER_BODYPAINT ) == 0 &&  -			getLocalDiscardLevel( LOCTEX_LOWER_SHOES ) == 0 &&  -			getLocalDiscardLevel( LOCTEX_LOWER_SOCKS ) == 0 &&  -			getLocalDiscardLevel( LOCTEX_LOWER_JACKET ) == 0 &&  -			getLocalDiscardLevel( LOCTEX_LOWER_UNDERPANTS ) == 0; -	} -	else if( layerset == mEyesLayerSet ) -	{ -		return getLocalDiscardLevel( LOCTEX_EYES_IRIS ) == 0; -	} -	else if( layerset == mSkirtLayerSet ) -	{ -		return getLocalDiscardLevel( LOCTEX_SKIRT ) == 0; +		if (layerset == mBakedTextureData[i].mTexLayerSet) +		{ +			const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); +			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); +				 local_tex_iter != baked_dict->mLocalTextures.end(); +				 local_tex_iter++) +			{ +				if (getLocalDiscardLevel(*local_tex_iter) != 0) +				{ +					return FALSE; +				} +			} +			return TRUE; +		}  	}  	llassert(0); @@ -7844,41 +7117,31 @@ BOOL LLVOAvatar::isLocalTextureDataFinal( LLTexLayerSet* layerset )  //-----------------------------------------------------------------------------  // isLocalTextureDataAvailable() -// Returns true is at least the lowest quality discard level exists for every texture +// Returns true if at least the lowest quality discard level exists for every texture  // in the layerset.  //-----------------------------------------------------------------------------  BOOL LLVOAvatar::isLocalTextureDataAvailable( LLTexLayerSet* layerset )  { -	if( layerset == mHeadLayerSet ) -	{ -		return getLocalDiscardLevel( LOCTEX_HEAD_BODYPAINT ) >= 0; -	} -	else if( layerset == mUpperBodyLayerSet ) +	/* if( layerset == mBakedTextureData[BAKED_HEAD].mTexLayerSet ) +	   return getLocalDiscardLevel( TEX_HEAD_BODYPAINT ) >= 0; */ +	for (LLVOAvatarDictionary::baked_map_t::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); +		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); +		 baked_iter++)  	{ -		return getLocalDiscardLevel( LOCTEX_UPPER_SHIRT ) >= 0 && -			getLocalDiscardLevel( LOCTEX_UPPER_BODYPAINT ) >= 0 && -			getLocalDiscardLevel( LOCTEX_UPPER_JACKET ) >= 0 &&  -			getLocalDiscardLevel( LOCTEX_UPPER_GLOVES ) >= 0 &&  -			getLocalDiscardLevel( LOCTEX_UPPER_UNDERSHIRT ) >= 0; -	} -	else if( layerset == mLowerBodyLayerSet ) -	{ -		return getLocalDiscardLevel( LOCTEX_LOWER_PANTS ) >= 0 && -			getLocalDiscardLevel( LOCTEX_LOWER_BODYPAINT ) >= 0 &&  -			getLocalDiscardLevel( LOCTEX_LOWER_SHOES ) >= 0 &&  -			getLocalDiscardLevel( LOCTEX_LOWER_SOCKS ) >= 0 &&  -			getLocalDiscardLevel( LOCTEX_LOWER_JACKET ) >= 0 &&  -			getLocalDiscardLevel( LOCTEX_LOWER_UNDERPANTS ) >= 0; -	} -	else if( layerset == mEyesLayerSet ) -	{ -		return getLocalDiscardLevel( LOCTEX_EYES_IRIS ) >= 0; -	} -	else if( layerset == mSkirtLayerSet ) -	{ -		return getLocalDiscardLevel( LOCTEX_SKIRT ) >= 0; +		const EBakedTextureIndex baked_index = baked_iter->first; +		if (layerset == mBakedTextureData[baked_index].mTexLayerSet) +		{ +			bool ret = true; +			const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = baked_iter->second; +			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); +				 local_tex_iter != baked_dict->mLocalTextures.end(); +				 local_tex_iter++) +			{ +				ret &= (getLocalDiscardLevel(*local_tex_iter) >= 0); +			} +			return ret; +		}  	} -  	llassert(0);  	return FALSE;  } @@ -7888,31 +7151,14 @@ BOOL LLVOAvatar::isLocalTextureDataAvailable( LLTexLayerSet* layerset )  // getBakedTE()  // Used by the LayerSet.  (Layer sets don't in general know what textures depend on them.)  //----------------------------------------------------------------------------- -LLVOAvatar::ETextureIndex LLVOAvatar::getBakedTE( LLTexLayerSet* layerset ) +ETextureIndex LLVOAvatar::getBakedTE( LLTexLayerSet* layerset )  { -	if( layerset == mHeadLayerSet ) +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		return TEX_HEAD_BAKED; -	} -	else -	if( layerset == mUpperBodyLayerSet ) -	{ -		return TEX_UPPER_BAKED; -	} -	else -	if( layerset == mLowerBodyLayerSet ) -	{ -		return TEX_LOWER_BAKED; -	} -	else -	if( layerset == mEyesLayerSet ) -	{ -		return TEX_EYES_BAKED; -	} -	else -	if( layerset == mSkirtLayerSet ) -	{ -		return TEX_SKIRT_BAKED; +		if (layerset == mBakedTextureData[i].mTexLayerSet ) +		{ +			return mBakedTextureData[i].mTextureIndex; +		}  	}  	llassert(0); @@ -7933,26 +7179,17 @@ void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )  	LLVOAvatar::cullAvatarsByPixelArea(); -	switch( te ) +	/* switch(te) +		case TEX_HEAD_BAKED: +			llinfos << "New baked texture: HEAD" << llendl; */ +	const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(te); +	if (text_dict->mIsBakedTexture) +	{ +		llinfos << "New baked texture: " << text_dict->mName << " UUID: " << uuid <<llendl; +	} +	else  	{ -	case TEX_HEAD_BAKED: -		llinfos << "New baked texture: HEAD" << llendl; -		break; -	case TEX_UPPER_BAKED: -		llinfos << "New baked texture: UPPER" << llendl; -		break; -	case TEX_LOWER_BAKED: -		llinfos << "New baked texture: LOWER" << llendl; -		break; -	case TEX_EYES_BAKED: -		llinfos << "New baked texture: EYES" << llendl; -		break; -	case TEX_SKIRT_BAKED: -		llinfos << "New baked texture: SKIRT" << llendl; -		break; -	default:  		llwarns << "New baked texture: unknown te " << te << llendl; -		break;  	}  	//	dumpAvatarTEs( "setNewBakedTexture() send" ); @@ -7965,28 +7202,15 @@ void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )  bool LLVOAvatar::hasPendingBakedUploads()  { -	bool head_pending = (mHeadLayerSet && mHeadLayerSet->getComposite()->uploadPending()); -	bool upper_pending = (mUpperBodyLayerSet && mUpperBodyLayerSet->getComposite()->uploadPending()); -	bool lower_pending = (mLowerBodyLayerSet && mLowerBodyLayerSet->getComposite()->uploadPending()); -	bool eyes_pending = (mEyesLayerSet && mEyesLayerSet->getComposite()->uploadPending()); -	bool skirt_pending = (mSkirtLayerSet && mSkirtLayerSet->getComposite()->uploadPending()); - -	//llinfos << "TAT: LLVOAvatar::hasPendingBakedUploads()" -	//	<< " head_pending " << head_pending -	//	<< " upper_pending " << upper_pending -	//	<< " lower_pending " << lower_pending -	//	<< " eyes_pending " << eyes_pending -	//	<< " skirt_pending " << skirt_pending -	//	<< llendl; - -	if (head_pending || upper_pending || lower_pending || eyes_pending || skirt_pending) -	{ -		return true; -	} -	else +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		return false; +		bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending()); +		if (upload_pending) +		{ +			return true; +		}  	} +	return false;  }  //----------------------------------------------------------------------------- @@ -7997,56 +7221,50 @@ void LLVOAvatar::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid )  {  	setTETexture( te, uuid ); -	switch(te) +	/* switch(te) +		case TEX_HEAD_BAKED: +			if( mHeadLayerSet ) +				mHeadLayerSet->cancelUpload(); */ +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -	case TEX_HEAD_BAKED: -		if( mHeadLayerSet ) +		if ( mBakedTextureData[i].mTextureIndex == te && mBakedTextureData[i].mTexLayerSet)  		{ -			mHeadLayerSet->cancelUpload(); -		}		 -		break; -	case TEX_UPPER_BAKED: -		if( mUpperBodyLayerSet ) -		{ -			mUpperBodyLayerSet->cancelUpload(); +			mBakedTextureData[i].mTexLayerSet->cancelUpload();  		} -		break; -	case TEX_LOWER_BAKED: -		if( mLowerBodyLayerSet ) +	} +} + +//----------------------------------------------------------------------------- +// releaseUnneccesaryTextures() +// release any component texture UUIDs for which we have a baked texture +//----------------------------------------------------------------------------- +void LLVOAvatar::releaseUnnecessaryTextures() +{ +	// Backwards Compat: detect if the baked hair texture actually wasn't sent, and if so set to default +	if (isTextureDefined(TEX_HAIR_BAKED) && getTEImage(TEX_HAIR_BAKED)->getID() == getTEImage(TEX_SKIRT_BAKED)->getID()) +	{ +		if (getTEImage(TEX_HAIR_BAKED)->getID() != IMG_INVISIBLE)  		{ -			mLowerBodyLayerSet->cancelUpload(); +			// Regression case of messaging system. Expected 21 textures, received 20. last texture is not valid so set to default +			setTETexture(TEX_HAIR_BAKED, IMG_DEFAULT_AVATAR);  		} -		break; -	case TEX_EYES_BAKED: -		if( mEyesLayerSet ) +	} + +	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) +	{ +		const LLVOAvatarDictionary::BakedDictionaryEntry * bakedDicEntry = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); +		// skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID +		if (!isTextureDefined(bakedDicEntry->mTextureIndex) +			&& ( (baked_index != BAKED_SKIRT) || isWearingWearableType(WT_SKIRT) ))  		{ -			mEyesLayerSet->cancelUpload(); +			continue;  		} -		break; -	case TEX_SKIRT_BAKED: -		if( mSkirtLayerSet ) + +		for (U8 texture = 0; texture < bakedDicEntry->mLocalTextures.size(); texture++)  		{ -			mSkirtLayerSet->cancelUpload(); +			const U8 te = (ETextureIndex)bakedDicEntry->mLocalTextures[texture]; +			setTETexture(te, IMG_DEFAULT_AVATAR);  		} -		break; - -		case TEX_HEAD_BODYPAINT: -		case TEX_UPPER_SHIRT: -		case TEX_LOWER_PANTS: -		case TEX_EYES_IRIS: -		case TEX_HAIR: -		case TEX_UPPER_BODYPAINT: -		case TEX_LOWER_BODYPAINT: -		case TEX_LOWER_SHOES: -		case TEX_LOWER_SOCKS: -		case TEX_UPPER_JACKET: -		case TEX_LOWER_JACKET: -		case TEX_UPPER_GLOVES: -		case TEX_UPPER_UNDERSHIRT: -		case TEX_LOWER_UNDERPANTS: -		case TEX_SKIRT: -		case TEX_NUM_ENTRIES: -			break;  	}  } @@ -8056,21 +7274,9 @@ void LLVOAvatar::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid )  //-----------------------------------------------------------------------------  void LLVOAvatar::onCustomizeStart()  { -	LLVOAvatar* avatar = gAgent.getAvatarObject(); -	if( avatar ) -	{ -		for( S32 i = 0; i < BAKED_TEXTURE_COUNT; i++ ) -		{ -			S32 tex_index = sBakedTextureIndices[i]; -			avatar->mSavedTE[ tex_index ] = avatar->getTEImage(tex_index)->getID(); -			avatar->setTEImage( tex_index, gImageList.getImage(IMG_DEFAULT_AVATAR) ); -		} - -		avatar->updateMeshTextures(); - -//		avatar->dumpAvatarTEs( "onCustomizeStart() send" ); -		gAgent.sendAgentSetAppearance(); -	} +	// We're no longer doing any baking or invalidating on entering  +	// appearance editing mode. Leaving function in place in case  +	// further changes require us to do something at this point - Nyx  }  //----------------------------------------------------------------------------- @@ -8079,29 +7285,31 @@ void LLVOAvatar::onCustomizeStart()  //-----------------------------------------------------------------------------  void LLVOAvatar::onCustomizeEnd()  { -	LLVOAvatar* avatar = gAgent.getAvatarObject(); -	if( !avatar ) return; +	LLVOAvatar *avatarp = gAgent.getAvatarObject(); +	if (avatarp) +	{ +		avatarp->invalidateAll(); +		avatarp->requestLayerSetUploads(); +	} +} -	LLHost target_host = avatar->getObjectHost(); -		for( S32 i = 0; i < BAKED_TEXTURE_COUNT; i++ ) +void LLVOAvatar::onChangeSelfInvisible(BOOL newvalue) +{ +	LLVOAvatar *avatarp = gAgent.getAvatarObject(); +	if (avatarp) +	{ +		if (newvalue)  		{ -			S32 tex_index = sBakedTextureIndices[i]; -			const LLUUID& saved = avatar->mSavedTE[ tex_index ]; -			if( !saved.isNull() ) -			{ -			avatar->setTEImage( tex_index, gImageList.getImageFromHost( saved, target_host ) ); -			} +			// we have just requested to set the avatar's baked textures to invisible +			avatarp->setInvisible(TRUE);  		} - -		avatar->updateMeshTextures(); - -		if( !LLApp::isExiting()) +		else  		{ -			avatar->requestLayerSetUploads(); +			avatarp->setInvisible(FALSE);  		} - -		gAgent.sendAgentSetAppearance();  	} +} +  BOOL LLVOAvatar::teToColorParams( ETextureIndex te, const char* param_name[3] )  { @@ -8181,7 +7389,7 @@ void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, B  	}  } -LLColor4  LLVOAvatar::getClothesColor( ETextureIndex te ) +LLColor4 LLVOAvatar::getClothesColor( ETextureIndex te )  {  	LLColor4 color;  	const char* param_name[3]; @@ -8198,56 +7406,36 @@ LLColor4  LLVOAvatar::getClothesColor( ETextureIndex te )  void LLVOAvatar::dumpAvatarTEs( const std::string& context ) -{ +{	 +	/* const char* te_name[] = { +			"TEX_HEAD_BODYPAINT   ", +			"TEX_UPPER_SHIRT      ", */  	llinfos << (mIsSelf ? "Self: " : "Other: ") << context << llendl; -	for( S32 i=0; i<TEX_NUM_ENTRIES; i++ ) +	for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); +		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); +		 iter++)  	{ -		const char* te_name[] = { -			"TEX_HEAD_BODYPAINT   ", -			"TEX_UPPER_SHIRT      ", -			"TEX_LOWER_PANTS      ", -			"TEX_EYES_IRIS        ", -			"TEX_HAIR             ", -			"TEX_UPPER_BODYPAINT  ", -			"TEX_LOWER_BODYPAINT  ", -			"TEX_LOWER_SHOES      ", -			"TEX_HEAD_BAKED       ", -			"TEX_UPPER_BAKED      ", -			"TEX_LOWER_BAKED      ", -			"TEX_EYES_BAKED       ", -			"TEX_LOWER_SOCKS      ", -			"TEX_UPPER_JACKET     ", -			"TEX_LOWER_JACKET     ", -			"TEX_UPPER_GLOVES     ", -			"TEX_UPPER_UNDERSHIRT ", -			"TEX_LOWER_UNDERPANTS ", -			"TEX_SKIRT            ", -			"TEX_SKIRT_BAKED      " -		}; - -		LLViewerImage* te_image = getTEImage(i); +		const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second; +		const LLViewerImage* te_image = getTEImage(iter->first);  		if( !te_image )  		{ -			llinfos << "       " << te_name[i] << ": null ptr" << llendl; +			llinfos << "       " << text_dict->mName << ": null ptr" << llendl;  		} -		else -		if( te_image->getID().isNull() ) +		else if( te_image->getID().isNull() )  		{ -			llinfos << "       " << te_name[i] << ": null UUID" << llendl; +			llinfos << "       " << text_dict->mName << ": null UUID" << llendl;  		} -		else -		if( te_image->getID() == IMG_DEFAULT ) +		else if( te_image->getID() == IMG_DEFAULT )  		{ -			llinfos << "       " << te_name[i] << ": IMG_DEFAULT" << llendl; +			llinfos << "       " << text_dict->mName << ": IMG_DEFAULT" << llendl;  		} -		else -		if( te_image->getID() == IMG_DEFAULT_AVATAR ) +		else if( te_image->getID() == IMG_DEFAULT_AVATAR )  		{ -			llinfos << "       " << te_name[i] << ": IMG_DEFAULT_AVATAR" << llendl; +			llinfos << "       " << text_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl;  		}  		else  		{ -			llinfos << "       " << te_name[i] << ": " << te_image->getID() << llendl; +			llinfos << "       " << text_dict->mName << ": " << te_image->getID() << llendl;  		}  	}  } @@ -8290,80 +7478,51 @@ void LLVOAvatar::updateAttachmentVisibility(U32 camera_mode)  // Given a texture entry, determine which wearable type owns it.  // static -LLUUID LLVOAvatar::getDefaultTEImageID( S32 te ) +LLUUID LLVOAvatar::getDefaultTEImageID(ETextureIndex index )  { -	switch( te ) +	/* switch( index ) +		case TEX_UPPER_SHIRT:		return LLUUID( gSavedSettings.getString("UIImgDefaultShirtUUID") ); */ +	const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); +	const std::string &default_image_name = text_dict->mDefaultImageName; +	if (default_image_name == "")  	{ -	case TEX_UPPER_SHIRT:		return LLUUID( gSavedSettings.getString("UIImgDefaultShirtUUID") ); -	case TEX_LOWER_PANTS:		return LLUUID( gSavedSettings.getString("UIImgDefaultPantsUUID") ); -	case TEX_EYES_IRIS:			return LLUUID( gSavedSettings.getString("UIImgDefaultEyesUUID") ); -	case TEX_HAIR:				return LLUUID( gSavedSettings.getString("UIImgDefaultHairUUID") ); -	case TEX_LOWER_SHOES:		return LLUUID( gSavedSettings.getString("UIImgDefaultShoesUUID") ); -	case TEX_LOWER_SOCKS:		return LLUUID( gSavedSettings.getString("UIImgDefaultSocksUUID") ); -	case TEX_UPPER_GLOVES:		return LLUUID( gSavedSettings.getString("UIImgDefaultGlovesUUID") ); -	 -	case TEX_UPPER_JACKET: -	case TEX_LOWER_JACKET:		return LLUUID( gSavedSettings.getString("UIImgDefaultJacketUUID") ); - -	case TEX_UPPER_UNDERSHIRT: -	case TEX_LOWER_UNDERPANTS:	return LLUUID( gSavedSettings.getString("UIImgDefaultUnderwearUUID") ); - -	case TEX_SKIRT:				return LLUUID( gSavedSettings.getString("UIImgDefaultSkirtUUID") ); - -	default:					return IMG_DEFAULT_AVATAR; +		return IMG_DEFAULT_AVATAR; +	} +	else +	{ +		return LLUUID(gSavedSettings.getString(default_image_name));  	}  } +void LLVOAvatar::setInvisible(BOOL newvalue) +{ +	if (newvalue) +	{ +		setCompositeUpdatesEnabled(FALSE); +		for (U32 i = 0; i < mBakedTextureData.size(); i++ ) +		{ +			setNewBakedTexture(mBakedTextureData[i].mTextureIndex, IMG_INVISIBLE); +		} +		gAgent.sendAgentSetAppearance(); +	} +	else +	{ +		setCompositeUpdatesEnabled(TRUE); +		invalidateAll(); +		requestLayerSetUploads(); +		gAgent.sendAgentSetAppearance(); +	} +}  // Given a texture entry, determine which wearable type owns it.  // static -EWearableType LLVOAvatar::getTEWearableType( S32 te ) +EWearableType LLVOAvatar::getTEWearableType(ETextureIndex index )  { -	switch( te ) -	{ -	case TEX_UPPER_SHIRT: -		return WT_SHIRT; - -	case TEX_LOWER_PANTS: -		return WT_PANTS; - -	case TEX_EYES_IRIS: -		return WT_EYES; - -	case TEX_HAIR: -		return WT_HAIR; -	 -	case TEX_HEAD_BODYPAINT: -	case TEX_UPPER_BODYPAINT: -	case TEX_LOWER_BODYPAINT: -		return WT_SKIN; - -	case TEX_LOWER_SHOES: -		return WT_SHOES; - -	case TEX_LOWER_SOCKS: -		return WT_SOCKS; - -	case TEX_UPPER_JACKET: -	case TEX_LOWER_JACKET: -		return WT_JACKET; - -	case TEX_UPPER_GLOVES: -		return WT_GLOVES; - -	case TEX_UPPER_UNDERSHIRT: -		return WT_UNDERSHIRT; - -	case TEX_LOWER_UNDERPANTS: -		return WT_UNDERPANTS; - -	case TEX_SKIRT: -		return WT_SKIRT; - -	default: -		return WT_INVALID; -	} +	/* switch(index) +		case TEX_UPPER_SHIRT: +			return WT_SHIRT; */ +	return LLVOAvatarDictionary::getInstance()->getTexture(index)->mWearableType;  }  // Unlike most wearable functions, this works for both self and other. @@ -8371,57 +7530,68 @@ BOOL LLVOAvatar::isWearingWearableType( EWearableType type )  {  	if (mIsDummy) return TRUE; -	ETextureIndex indicator_te;  	switch( type )  	{ -		case WT_SHIRT: -			indicator_te = TEX_UPPER_SHIRT; -			break; - -		case WT_PANTS:  -			indicator_te = TEX_LOWER_PANTS; -			break; - -		case WT_SHOES: -			indicator_te = TEX_LOWER_SHOES; -			break; - -		case WT_SOCKS: -			indicator_te = TEX_LOWER_SOCKS; -			break; - -		case WT_JACKET: -			indicator_te = TEX_UPPER_JACKET; -			// Note: no need to test both upper and lower jacket -			break; - -		case WT_GLOVES: -			indicator_te = TEX_UPPER_GLOVES; -			break; - -		case WT_UNDERSHIRT: -			indicator_te = TEX_UPPER_UNDERSHIRT; -			break; - -		case WT_UNDERPANTS: -			indicator_te = TEX_LOWER_UNDERPANTS; -			break; - -		case WT_SKIRT: -			indicator_te = TEX_SKIRT; -			break; -		  		case WT_SHAPE:  		case WT_SKIN:  		case WT_HAIR:  		case WT_EYES:  			return TRUE;  // everyone has all bodyparts -  		default: -			return FALSE; +			break; // Do nothing  	} -	return ( getTEImage(indicator_te)->getID() != IMG_DEFAULT_AVATAR ); +	/* switch(type) +		case WT_SHIRT: +			indicator_te = TEX_UPPER_SHIRT; */ +	for (LLVOAvatarDictionary::texture_map_t::const_iterator tex_iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); +		 tex_iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); +		 tex_iter++) +	{ +		const LLVOAvatarDefines::ETextureIndex index = tex_iter->first; +		const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = tex_iter->second; +		if (text_dict->mWearableType == type) +		{ +			// If you're checking your own clothing, check the component texture +			if (mIsSelf) +			{ +				if (isTextureDefined(index)) +				{ +					return TRUE; +				} +				else +				{ +					return FALSE; +				} +			} + +			// 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). +			const std::string name = text_dict->mName; +			for (LLVOAvatarDictionary::baked_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); +				iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); +				iter++) +			{ +				const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = iter->second; +				if (baked_dict->mName == name) +				{ +					if (isTextureDefined(baked_dict->mTextureIndex)) +					{ +						return TRUE; +					} +					else +					{ +						return FALSE; +					} +				} +			} +			return FALSE; +		} +	} +	return FALSE;  } @@ -8446,12 +7616,12 @@ void LLVOAvatar::clampAttachmentPositions()  	}  } -BOOL LLVOAvatar::hasHUDAttachment() +BOOL LLVOAvatar::hasHUDAttachment() const  { -	for (attachment_map_t::iterator iter = mAttachmentPoints.begin();  +	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();   		 iter != mAttachmentPoints.end(); )  	{ -		attachment_map_t::iterator curiter = iter++; +		attachment_map_t::const_iterator curiter = iter++;  		LLViewerJointAttachment* attachment = curiter->second;  		if (attachment->getIsHUDAttachment() && attachment->getObject())  		{ @@ -8461,13 +7631,13 @@ BOOL LLVOAvatar::hasHUDAttachment()  	return FALSE;  } -LLBBox LLVOAvatar::getHUDBBox() +LLBBox LLVOAvatar::getHUDBBox() const  {  	LLBBox bbox; -	for (attachment_map_t::iterator iter = mAttachmentPoints.begin();  +	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();   		 iter != mAttachmentPoints.end(); )  	{ -		attachment_map_t::iterator curiter = iter++; +		attachment_map_t::const_iterator curiter = iter++;  		LLViewerJointAttachment* attachment = curiter->second;  		if (attachment->getIsHUDAttachment() && attachment->getObject())  		{ @@ -8503,50 +7673,23 @@ void LLVOAvatar::onFirstTEMessageReceived()  	{  		mFirstTEMessageReceived = TRUE; -		BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -		BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -		BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -		BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); -		BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); - -		// Use any baked textures that we have even if they haven't downloaded yet. -		// (That is, don't do a transition from unbaked to baked.) -		if( head_baked ) -		{ -			mLastHeadBakedID = getTEImage( TEX_HEAD_BAKED )->getID(); -			LLViewerImage* image = getTEImage( TEX_HEAD_BAKED ); -			image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));	 -			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) ); -		} - -		if( upper_baked ) +		for (U32 i = 0; i < mBakedTextureData.size(); i++)  		{ -			mLastUpperBodyBakedID = getTEImage( TEX_UPPER_BAKED )->getID(); -			LLViewerImage* image = getTEImage( TEX_UPPER_BAKED ); -			image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));	 -			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) ); -		} -		 -		if( lower_baked ) -		{ -			mLastLowerBodyBakedID = getTEImage( TEX_LOWER_BAKED )->getID(); -			LLViewerImage* image = getTEImage( TEX_LOWER_BAKED ); -			image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));	 -			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) ); -		} - -		if( eyes_baked ) -		{ -			mLastEyesBakedID = getTEImage( TEX_EYES_BAKED )->getID(); -			LLViewerImage* image = getTEImage( TEX_EYES_BAKED ); -			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) ); -		} +			bool layer_baked = isTextureDefined(mBakedTextureData[i].mTextureIndex); -		if( skirt_baked ) -		{ -			mLastSkirtBakedID = getTEImage( TEX_SKIRT_BAKED )->getID(); -			LLViewerImage* image = getTEImage( TEX_SKIRT_BAKED ); -			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) ); +			// Use any baked textures that we have even if they haven't downloaded yet. +			// (That is, don't do a transition from unbaked to baked.) +			if (layer_baked) +			{ +				LLViewerImage* image = getTEImage( mBakedTextureData[i].mTextureIndex ); +				mBakedTextureData[i].mLastTextureIndex = image->getID(); +				// If we have more than one texture for the other baked layers, we'll want to call this for them too. +				if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) ) +				{ +					image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID )); +				} +				image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) ); +			}  		}  		updateMeshTextures(); @@ -8593,11 +7736,13 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	unpackTEMessage(mesgsys, _PREHASH_ObjectData);  //	dumpAvatarTEs( "POST processAvatarAppearance()" ); -//	llinfos << "Received AvatarAppearance: " << (mIsSelf ? "(self): " : "(other): " ) <<  -//		(( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR )  ? "HEAD " : "head " ) << -//		(( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "UPPER " : "upper " ) << -//		(( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "LOWER " : "lower " ) << -//		(( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR )  ? "EYES" : "eyes" ) << llendl; +	//llinfos << "Received AvatarAppearance: " << (mIsSelf ? "(self): " : "(other): ")  << std::endl << +	//	(isTextureDefined(TEX_HEAD_BAKED)  ? "HEAD " : "head " ) << (getTEImage(TEX_HEAD_BAKED)->getID()) << std::endl << +	//	(isTextureDefined(TEX_UPPER_BAKED) ? "UPPER " : "upper " ) << (getTEImage(TEX_UPPER_BAKED)->getID()) << std::endl << +	//	(isTextureDefined(TEX_LOWER_BAKED) ? "LOWER " : "lower " ) << (getTEImage(TEX_LOWER_BAKED)->getID()) << std::endl << +	//	(isTextureDefined(TEX_SKIRT_BAKED) ? "SKIRT " : "skirt " ) << (getTEImage(TEX_SKIRT_BAKED)->getID()) << std::endl << +	//	(isTextureDefined(TEX_HAIR_BAKED) ? "HAIR" : "hair " ) << (getTEImage(TEX_HAIR_BAKED)->getID()) << std::endl << +	//	(isTextureDefined(TEX_EYES_BAKED)  ? "EYES" : "eyes" ) << (getTEImage(TEX_EYES_BAKED)->getID()) << llendl ;  	if( !mFirstTEMessageReceived )  	{ @@ -8605,6 +7750,12 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	}  	setCompositeUpdatesEnabled( FALSE ); + +	if (!mIsSelf) +	{ +		releaseUnnecessaryTextures(); +	} +	  	updateMeshTextures(); // enables updates for laysets without baked textures.  	// parse visual params @@ -8652,7 +7803,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  						param->setAnimationTarget(newWeight, FALSE);  					}  				} -				  				param = getNextVisualParam();  			}  		} @@ -8726,28 +7876,20 @@ void LLVOAvatar::getAnimNames( LLDynamicArray<std::string>* names )  void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )  { -	//llinfos << "onBakedTextureMasksLoaded: " << src_vi->getID() << llendl; -	LLMemType mt(LLMemType::MTYPE_AVATAR); -	 -	LLUUID id = src_vi->getID(); +	if (!userdata) return; -	if (!userdata) -	{ -		return; -	} +	//llinfos << "onBakedTextureMasksLoaded: " << src_vi->getID() << llendl; +	const LLMemType mt(LLMemType::MTYPE_AVATAR); +	const LLUUID id = src_vi->getID();  	LLTextureMaskData* maskData = (LLTextureMaskData*) userdata;  	LLVOAvatar* self = (LLVOAvatar*) gObjectList.findObject( maskData->mAvatarID );  	// if discard level is 2 less than last discard level we processed, or we hit 0,  	// then generate morph masks -	if( self && success && (discard_level < maskData->mLastDiscardLevel - 2 || discard_level == 0) ) +	if(self && success && (discard_level < maskData->mLastDiscardLevel - 2 || discard_level == 0))  	{ -		LLViewerImage* head_baked =		self->getTEImage( TEX_HEAD_BAKED ); -		LLViewerImage* upper_baked =	self->getTEImage( TEX_UPPER_BAKED ); -		LLViewerImage* lower_baked =	self->getTEImage( TEX_LOWER_BAKED ); -	 -		if( aux_src && aux_src->getComponents() == 1 ) +		if(aux_src && aux_src->getComponents() == 1)  		{  			if (!aux_src->getData())  			{ @@ -8770,70 +7912,49 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi,  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); -			if( id == head_baked->getID() ) -			{ -				if (self->mHeadLayerSet) -				{ -					//llinfos << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << llendl; -					self->mHeadLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); -					maskData->mLastDiscardLevel = discard_level; -					self->mHeadMaskDiscard = discard_level; -					if (self->mHeadMaskTexName) -					{ -						LLImageGL::deleteTextures(1, &self->mHeadMaskTexName); -					} -					self->mHeadMaskTexName = gl_name; -				} -				else -				{ -					llwarns << "onBakedTextureMasksLoaded: no mHeadLayerSet." << llendl; -				} -			} -			else -			if( id == upper_baked->getID() ) -			{ -				if ( self->mUpperBodyLayerSet) -				{ -					//llinfos << "onBakedTextureMasksLoaded for upper body " << id << " discard = " << discard_level << llendl; -					self->mUpperBodyLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); -					maskData->mLastDiscardLevel = discard_level; -					self->mUpperMaskDiscard = discard_level; -					if (self->mUpperMaskTexName) -					{ -						LLImageGL::deleteTextures(1, &self->mUpperMaskTexName); -					} -					self->mUpperMaskTexName = gl_name; -				} -				else -				{ -					llwarns << "onBakedTextureMasksLoaded: no mHeadLayerSet." << llendl; -				} -			} -			else -			if( id == lower_baked->getID() ) +			/* if( id == head_baked->getID() ) +			     if (self->mBakedTextureData[BAKED_HEAD].mTexLayerSet) +				     //llinfos << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << llendl; +					 self->mBakedTextureData[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); +					 maskData->mLastDiscardLevel = discard_level; */ +			bool found_texture_id = false; +			for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); +				 iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); +				 iter++)  			{ -				if ( self->mLowerBodyLayerSet ) + +				const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second; +				if (text_dict->mIsUsedByBakedTexture)  				{ -					//llinfos << "onBakedTextureMasksLoaded for lower body " << id << " discard = " << discard_level << llendl; -					self->mLowerBodyLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); -					maskData->mLastDiscardLevel = discard_level; -					self->mLowerMaskDiscard = discard_level; -					if (self->mLowerMaskTexName) +					const ETextureIndex texture_index = iter->first; +					const LLViewerImage *baked_img = self->getTEImage(texture_index); +					if (id == baked_img->getID())  					{ -						LLImageGL::deleteTextures(1, &self->mLowerMaskTexName); +						const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; +						if (self->mBakedTextureData[baked_index].mTexLayerSet) +						{ +							//llinfos << "onBakedTextureMasksLoaded for " << text_dict->mName << " " << id << " discard = " << discard_level << llendl; +							self->mBakedTextureData[baked_index].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); +							maskData->mLastDiscardLevel = discard_level; +							if (self->mBakedTextureData[baked_index].mMaskTexName) +							{ +								LLImageGL::deleteTextures(1, &(self->mBakedTextureData[baked_index].mMaskTexName)); +							} +							self->mBakedTextureData[baked_index].mMaskTexName = gl_name; +						} +						else +						{ +							llwarns << "onBakedTextureMasksLoaded: no LayerSet for " << text_dict->mName << "." << llendl; +						} +						found_texture_id = true; +						break;  					} -					self->mLowerMaskTexName = gl_name; -				} -				else -				{ -					llwarns << "onBakedTextureMasksLoaded: no mHeadLayerSet." << llendl;  				}  			} -			else +			if (!found_texture_id)  			{  				llinfos << "onBakedTextureMasksLoaded(): unexpected image id: " << id << llendl;  			} -  			self->dirtyMesh();  		}  		else @@ -8848,7 +7969,6 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi,  	{  		delete maskData;  	} -  }  // static @@ -8895,109 +8015,34 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLIma  // Called when baked texture is loaded and also when we start up with a baked texture  void LLVOAvatar::useBakedTexture( const LLUUID& id )  { -//	llinfos << "useBakedTexture" << llendl; -	LLViewerImage* head_baked =		getTEImage( TEX_HEAD_BAKED ); -	LLViewerImage* upper_baked =	getTEImage( TEX_UPPER_BAKED ); -	LLViewerImage* lower_baked =	getTEImage( TEX_LOWER_BAKED ); -	LLViewerImage* eyes_baked =		getTEImage( TEX_EYES_BAKED ); -	LLViewerImage* skirt_baked =	getTEImage( TEX_SKIRT_BAKED ); - -	if( id == head_baked->getID() ) -	{ -		mHeadBakedLoaded = TRUE; -		 -		mLastHeadBakedID = id; -		mHeadMesh0.setTexture( head_baked ); -		mHeadMesh1.setTexture( head_baked ); -		mHeadMesh2.setTexture( head_baked ); -		mHeadMesh3.setTexture( head_baked ); -		mHeadMesh4.setTexture( head_baked ); -		mEyeLashMesh0.setTexture( head_baked ); -		if( mHeadLayerSet ) -		{ -			mHeadLayerSet->destroyComposite(); -		} -		setLocalTexture( LOCTEX_HEAD_BODYPAINT,		getTEImage( TEX_HEAD_BODYPAINT ),	TRUE ); -	} -	else -	if( id == upper_baked->getID() ) -	{ -		mUpperBakedLoaded = TRUE; - -		mLastUpperBodyBakedID = id; -		mUpperBodyMesh0.setTexture( upper_baked ); -		mUpperBodyMesh1.setTexture( upper_baked ); -		mUpperBodyMesh2.setTexture( upper_baked ); -		mUpperBodyMesh3.setTexture( upper_baked ); -		mUpperBodyMesh4.setTexture( upper_baked ); -		if( mUpperBodyLayerSet ) -		{ -			mUpperBodyLayerSet->destroyComposite(); -		} - -		setLocalTexture( LOCTEX_UPPER_SHIRT,		getTEImage( TEX_UPPER_SHIRT ),		TRUE ); -		setLocalTexture( LOCTEX_UPPER_BODYPAINT,	getTEImage( TEX_UPPER_BODYPAINT ),	TRUE ); -		setLocalTexture( LOCTEX_UPPER_JACKET,		getTEImage( TEX_UPPER_JACKET ),		TRUE ); -		setLocalTexture( LOCTEX_UPPER_GLOVES,		getTEImage( TEX_UPPER_GLOVES ),		TRUE ); -		setLocalTexture( LOCTEX_UPPER_UNDERSHIRT,	getTEImage( TEX_UPPER_UNDERSHIRT ),	TRUE ); -	} -	else -	if( id == lower_baked->getID() ) -	{ -		mLowerBakedLoaded = TRUE; - -		mLastLowerBodyBakedID = id; -		mLowerBodyMesh0.setTexture( lower_baked ); -		mLowerBodyMesh1.setTexture( lower_baked ); -		mLowerBodyMesh2.setTexture( lower_baked ); -		mLowerBodyMesh3.setTexture( lower_baked ); -		mLowerBodyMesh4.setTexture( lower_baked ); -		if( mLowerBodyLayerSet ) -		{ -			mLowerBodyLayerSet->destroyComposite(); -		} - -		setLocalTexture( LOCTEX_LOWER_PANTS,		getTEImage( TEX_LOWER_PANTS ),		TRUE ); -		setLocalTexture( LOCTEX_LOWER_BODYPAINT,	getTEImage( TEX_LOWER_BODYPAINT ),	TRUE ); -		setLocalTexture( LOCTEX_LOWER_SHOES,		getTEImage( TEX_LOWER_SHOES ),		TRUE ); -		setLocalTexture( LOCTEX_LOWER_SOCKS,		getTEImage( TEX_LOWER_SOCKS ),		TRUE ); -		setLocalTexture( LOCTEX_LOWER_JACKET,		getTEImage( TEX_LOWER_JACKET ),		TRUE ); -		setLocalTexture( LOCTEX_LOWER_UNDERPANTS,	getTEImage( TEX_LOWER_UNDERPANTS ),	TRUE ); -	} -	else -	if( id == eyes_baked->getID() ) -	{ -		mEyesBakedLoaded = TRUE; - -		mLastEyesBakedID = id; -		mEyeBallLeftMesh0.setTexture(  eyes_baked ); -		mEyeBallLeftMesh1.setTexture(  eyes_baked ); -		mEyeBallRightMesh0.setTexture( eyes_baked ); -		mEyeBallRightMesh1.setTexture( eyes_baked ); -		if( mEyesLayerSet ) -		{ -			mEyesLayerSet->destroyComposite(); -		} - -		setLocalTexture( LOCTEX_EYES_IRIS,			getTEImage( TEX_EYES_IRIS ), TRUE ); -	} -	else -	if( id == skirt_baked->getID() ) +	/* if(id == head_baked->getID()) +		 mHeadBakedLoaded = TRUE; +		 mLastHeadBakedID = id; +		 mHeadMesh0.setTexture( head_baked ); +		 mHeadMesh1.setTexture( head_baked ); */ +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		mSkirtBakedLoaded = TRUE; - -		mLastSkirtBakedID = id; -		mSkirtMesh0.setTexture( skirt_baked ); -		mSkirtMesh1.setTexture( skirt_baked ); -		mSkirtMesh2.setTexture( skirt_baked ); -		mSkirtMesh3.setTexture( skirt_baked ); -		mSkirtMesh4.setTexture( skirt_baked ); -		if( mSkirtLayerSet ) +		LLViewerImage* image_baked = getTEImage( mBakedTextureData[i].mTextureIndex ); +		if (id == image_baked->getID())  		{ -			mSkirtLayerSet->destroyComposite(); +			mBakedTextureData[i].mIsLoaded = true; +			mBakedTextureData[i].mLastTextureIndex = id; +			for (U32 k = 0; k < mBakedTextureData[i].mMeshes.size(); k++) +			{ +				mBakedTextureData[i].mMeshes[k]->setTexture( image_baked ); +			} +			if (mBakedTextureData[i].mTexLayerSet) +			{ +				mBakedTextureData[i].mTexLayerSet->destroyComposite(); +			} +			const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); +			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); +				 local_tex_iter != baked_dict->mLocalTextures.end(); +				 local_tex_iter++) +			{ +				setLocalTexture(*local_tex_iter, getTEImage(*local_tex_iter), TRUE); +			}  		} - -		setLocalTexture( LOCTEX_SKIRT,				getTEImage( TEX_SKIRT ), TRUE );  	}  	dirtyMesh(); @@ -9036,11 +8081,11 @@ void LLVOAvatar::dumpArchetypeXML( void* )  			}  		} -		for( S32 te = 0; te < TEX_NUM_ENTRIES; te++ ) +		for(U8 te = 0; te < TEX_NUM_INDICES; te++)  		{ -			if( LLVOAvatar::getTEWearableType( te ) == type ) +			if( LLVOAvatar::getTEWearableType((ETextureIndex)te) == type )  			{ -				LLViewerImage* te_image = avatar->getTEImage( te ); +				LLViewerImage* te_image = avatar->getTEImage((ETextureIndex)te);  				if( te_image )  				{  					std::string uuid_str; @@ -9093,39 +8138,39 @@ S32 LLVOAvatar::getUnbakedPixelAreaRank()  	return 0;  } +struct CompareScreenAreaGreater +{ +	bool operator()(const LLCharacter* const& lhs, const LLCharacter* const& rhs) +	{ +		return lhs->getPixelArea() > rhs->getPixelArea(); +	} +}; +  // static  void LLVOAvatar::cullAvatarsByPixelArea()  {  	std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater());  	// Update the avatars that have changed status -	S32 comp_rank = 1;  	U32 rank = 0;  	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();  		iter != LLCharacter::sInstances.end(); ++iter)  	{  		LLVOAvatar* inst = (LLVOAvatar*) *iter;  		BOOL culled; -		if( inst->isDead() ) -		{ -			culled = TRUE; -		} -		else if( inst->isSelf() || inst->isFullyBaked() ) +		if (inst->isSelf() || inst->isFullyBaked())  		{  			culled = FALSE;  		} -		else +		else   		{ -			culled = (comp_rank > LLVOAvatar::sMaxOtherAvatarsToComposite) || (inst->mPixelArea < MIN_PIXEL_AREA_FOR_COMPOSITE); -			comp_rank++; +			culled = TRUE;  		} -		if( inst->mCulled != culled ) +		if (inst->mCulled != culled)  		{  			inst->mCulled = culled; -  			lldebugs << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << llendl; -  			inst->updateMeshTextures();  		} @@ -9140,9 +8185,9 @@ void LLVOAvatar::cullAvatarsByPixelArea()  	}  	S32 grey_avatars = 0; -	if( LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars) ) +	if ( LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars) )  	{ -		LLVOAvatar::deleteCachedImages(); +		LLVOAvatar::deleteCachedImages(false);  	}  	else  	{ @@ -9174,52 +8219,31 @@ const LLUUID& LLVOAvatar::grabLocalTexture(ETextureIndex index)  BOOL LLVOAvatar::canGrabLocalTexture(ETextureIndex index)  {  	// Check if the texture hasn't been baked yet. -	if ( getTEImage( index )->getID() == IMG_DEFAULT_AVATAR ) +	if (!isTextureDefined(index))  	{  		lldebugs << "getTEImage( " << (U32) index << " )->getID() == IMG_DEFAULT_AVATAR" << llendl;  		return FALSE;  	} +	if (gAgent.isGodlike()) +		return TRUE; +  	// Check permissions of textures that show up in the  	// baked texture.  We don't want people copying people's  	// work via baked textures. -	std::vector<ETextureIndex> textures; -	switch (index) -	{ -	case TEX_EYES_BAKED: -		textures.push_back(TEX_EYES_IRIS); -		break; -	case TEX_HEAD_BAKED: -		textures.push_back(TEX_HEAD_BODYPAINT); -		break; -	case TEX_UPPER_BAKED: -		textures.push_back(TEX_UPPER_BODYPAINT); -		textures.push_back(TEX_UPPER_UNDERSHIRT); -		textures.push_back(TEX_UPPER_SHIRT); -		textures.push_back(TEX_UPPER_JACKET); -		textures.push_back(TEX_UPPER_GLOVES); -		break; -	case TEX_LOWER_BAKED: -		textures.push_back(TEX_LOWER_BODYPAINT); -		textures.push_back(TEX_LOWER_UNDERPANTS); -		textures.push_back(TEX_LOWER_PANTS); -		textures.push_back(TEX_LOWER_JACKET); -		textures.push_back(TEX_LOWER_SOCKS); -		textures.push_back(TEX_LOWER_SHOES); -		break; -	case TEX_SKIRT_BAKED: -		textures.push_back(TEX_SKIRT); -		break; -	default: -		return FALSE; -		break; -	} - -	std::vector<ETextureIndex>::iterator iter = textures.begin(); -	std::vector<ETextureIndex>::iterator end  = textures.end(); -	for (; iter != end; ++iter) -	{ -		ETextureIndex t_index = (*iter); +	/* switch(index) +		case TEX_EYES_BAKED: +			textures.push_back(TEX_EYES_IRIS); */ +	const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); +	if (!text_dict->mIsUsedByBakedTexture) return FALSE; + +	const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; +	const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index); +	for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin(); +		 iter != baked_dict->mLocalTextures.end(); +		 iter++) +	{ +		const ETextureIndex t_index = (*iter);  		lldebugs << "Checking index " << (U32) t_index << llendl;  		const LLUUID& texture_id = getTEImage( t_index )->getID();  		if (texture_id != IMG_DEFAULT_AVATAR) @@ -9266,62 +8290,43 @@ void LLVOAvatar::dumpLocalTextures()  {  	llinfos << "Local Textures:" << llendl; -	const char* names[] = { -		"Shirt     ", -		"UpperTatoo", -		"Pants     ", -		"LowerTatoo", -		"Head Tatoo", -		"Shoes     ", -		"Socks     ", -		"Upper Jckt", -		"Lower Jckt", -		"Gloves    ", -		"Undershirt", -		"Underpants", -		"Iris      ", -		"Skirt      "}; - -	ETextureIndex baked_equiv[] = { -		TEX_UPPER_BAKED, -		TEX_UPPER_BAKED, -		TEX_LOWER_BAKED, -		TEX_LOWER_BAKED, -		TEX_HEAD_BAKED, -		TEX_LOWER_BAKED, -		TEX_LOWER_BAKED, -		TEX_UPPER_BAKED, -		TEX_LOWER_BAKED, -		TEX_UPPER_BAKED, +	/* ETextureIndex baked_equiv[] = {  		TEX_UPPER_BAKED, -		TEX_LOWER_BAKED, -		TEX_EYES_BAKED, -		TEX_SKIRT_BAKED }; +	   if (isTextureDefined(baked_equiv[i])) */ +	for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); +		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); +		 iter++) +	{ +		const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second; +		if (!text_dict->mIsLocalTexture || !text_dict->mIsUsedByBakedTexture) +			continue; +		const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; +		const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex; -	for( S32 i = 0; i < LOCTEX_NUM_ENTRIES; i++ ) -	{ -		if( getTEImage( baked_equiv[i] )->getID() != IMG_DEFAULT_AVATAR ) +		const std::string &name = text_dict->mName; +		const LocalTextureData &local_tex_data = mLocalTextureData[iter->first]; +		if (isTextureDefined(baked_equiv))  		{  #if LL_RELEASE_FOR_DOWNLOAD  			// End users don't get to trivially see avatar texture IDs, makes textures  			// easier to steal. JC -			llinfos << "LocTex " << names[i] << ": Baked " << llendl; +			llinfos << "LocTex " << name << ": Baked " << llendl;  #else -			llinfos << "LocTex " << names[i] << ": Baked " << getTEImage( baked_equiv[i] )->getID() << llendl; +			llinfos << "LocTex " << name << ": Baked " << getTEImage( baked_equiv )->getID() << llendl;  #endif  		} -		else if (mLocalTexture[i].notNull()) +		else if (local_tex_data.mImage.notNull())  		{ -			if( mLocalTexture[i]->getID() == IMG_DEFAULT_AVATAR ) +			if( local_tex_data.mImage->getID() == IMG_DEFAULT_AVATAR )  			{ -				llinfos << "LocTex " << names[i] << ": None" << llendl; +				llinfos << "LocTex " << name << ": None" << llendl;  			}  			else  			{ -				LLViewerImage* image = mLocalTexture[i]; +				const LLViewerImage* image = local_tex_data.mImage; -				llinfos << "LocTex " << names[i] << ": " +				llinfos << "LocTex " << name << ": "  						<< "Discard " << image->getDiscardLevel() << ", "  						<< "(" << image->getWidth() << ", " << image->getHeight() << ") "   #if !LL_RELEASE_FOR_DOWNLOAD @@ -9335,7 +8340,7 @@ void LLVOAvatar::dumpLocalTextures()  		}  		else  		{ -			llinfos << "LocTex " << names[i] << ": No LLViewerImage" << llendl; +			llinfos << "LocTex " << name << ": No LLViewerImage" << llendl;  		}  	}  } @@ -9354,30 +8359,25 @@ void LLVOAvatar::startAppearanceAnimation(BOOL set_by_user, BOOL play_sound)  void LLVOAvatar::removeMissingBakedTextures()  {	 -	if (!mIsSelf) -	{ -		return; -	} -	BOOL removed = FALSE; +	if (!mIsSelf) return; -	for( S32 i = 0; i < BAKED_TEXTURE_COUNT; i++ ) +	BOOL removed = FALSE; +	for (U32 i = 0; i < mBakedTextureData.size(); i++)  	{ -		S32 te = sBakedTextureIndices[i]; - -		if( getTEImage( te )->isMissingAsset() ) +		const S32 te = mBakedTextureData[i].mTextureIndex; +		if (getTEImage(te)->isMissingAsset())  		{ -			setTEImage( te, gImageList.getImage(IMG_DEFAULT_AVATAR) ); +			setTEImage(te, gImageList.getImage(IMG_DEFAULT_AVATAR));  			removed = TRUE;  		}  	} -	if( removed ) +	if (removed)  	{ -		invalidateComposite( mEyesLayerSet,			FALSE ); -		invalidateComposite( mHeadLayerSet,			FALSE ); -		invalidateComposite( mUpperBodyLayerSet,	FALSE ); -		invalidateComposite( mLowerBodyLayerSet,	FALSE ); -		invalidateComposite( mSkirtLayerSet,		FALSE ); +		for(U32 i = 0; i < mBakedTextureData.size(); i++) +		{ +			invalidateComposite(mBakedTextureData[i].mTexLayerSet, FALSE); +		}  		updateMeshTextures();  		requestLayerSetUploads();  	} @@ -9385,15 +8385,15 @@ void LLVOAvatar::removeMissingBakedTextures()  //----------------------------------------------------------------------------- -// LLVOAvatarInfo +// LLVOAvatarXmlInfo  //----------------------------------------------------------------------------- -LLVOAvatarInfo::LLVOAvatarInfo() +LLVOAvatarXmlInfo::LLVOAvatarXmlInfo()  	: mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)  {  } -LLVOAvatarInfo::~LLVOAvatarInfo() +LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()  {  	std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());  	std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());		 @@ -9514,7 +8514,7 @@ BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)  //-----------------------------------------------------------------------------  // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree  //----------------------------------------------------------------------------- -BOOL LLVOAvatarInfo::parseXmlSkeletonNode(LLXmlTreeNode* root) +BOOL LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)  {  	LLXmlTreeNode* node = root->getChildByName( "skeleton" );  	if( !node ) @@ -9620,7 +8620,7 @@ BOOL LLVOAvatarInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)  //-----------------------------------------------------------------------------  // parseXmlMeshNodes(): parses <mesh> nodes from XML tree  //----------------------------------------------------------------------------- -BOOL LLVOAvatarInfo::parseXmlMeshNodes(LLXmlTreeNode* root) +BOOL LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)  {  	for (LLXmlTreeNode* node = root->getChildByName( "mesh" );  		 node; @@ -9710,7 +8710,7 @@ BOOL LLVOAvatarInfo::parseXmlMeshNodes(LLXmlTreeNode* root)  //-----------------------------------------------------------------------------  // parseXmlColorNodes(): parses <global_color> nodes from XML tree  //----------------------------------------------------------------------------- -BOOL LLVOAvatarInfo::parseXmlColorNodes(LLXmlTreeNode* root) +BOOL LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)  {  	for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );  		 color_node; @@ -9772,7 +8772,7 @@ BOOL LLVOAvatarInfo::parseXmlColorNodes(LLXmlTreeNode* root)  //-----------------------------------------------------------------------------  // parseXmlLayerNodes(): parses <layer_set> nodes from XML tree  //----------------------------------------------------------------------------- -BOOL LLVOAvatarInfo::parseXmlLayerNodes(LLXmlTreeNode* root) +BOOL LLVOAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)  {  	for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );  		 layer_node; @@ -9796,7 +8796,7 @@ BOOL LLVOAvatarInfo::parseXmlLayerNodes(LLXmlTreeNode* root)  //-----------------------------------------------------------------------------  // parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree  //----------------------------------------------------------------------------- -BOOL LLVOAvatarInfo::parseXmlDriverNodes(LLXmlTreeNode* root) +BOOL LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)  {  	LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );  	if( driver ) @@ -9874,41 +8874,17 @@ std::string LLVOAvatar::getFullname() const  LLTexLayerSet* LLVOAvatar::getLayerSet(ETextureIndex index) const  { -	switch( index ) +	/* switch(index) +		case TEX_HEAD_BAKED: +		case TEX_HEAD_BODYPAINT: +			return mHeadLayerSet; */ +	const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); +	if (text_dict->mIsUsedByBakedTexture)  	{ -	case TEX_HEAD_BAKED: -	case TEX_HEAD_BODYPAINT: -		return mHeadLayerSet; - -	case TEX_UPPER_BAKED: -	case TEX_UPPER_SHIRT: -	case TEX_UPPER_BODYPAINT: -	case TEX_UPPER_JACKET: -	case TEX_UPPER_GLOVES: -	case TEX_UPPER_UNDERSHIRT: -		return mUpperBodyLayerSet; - -	case TEX_LOWER_BAKED: -	case TEX_LOWER_PANTS: -	case TEX_LOWER_BODYPAINT: -	case TEX_LOWER_SHOES: -	case TEX_LOWER_SOCKS: -	case TEX_LOWER_JACKET: -	case TEX_LOWER_UNDERPANTS: -		return mLowerBodyLayerSet; -	 -	case TEX_EYES_BAKED: -	case TEX_EYES_IRIS: -		return mEyesLayerSet; - -	case TEX_SKIRT_BAKED: -	case TEX_SKIRT: -		return mSkirtLayerSet; - -	case TEX_HAIR: -	default: -		return NULL; +		const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; +		return mBakedTextureData[baked_index].mTexLayerSet;  	} +	return NULL;  }  LLHost LLVOAvatar::getObjectHost() const @@ -9929,15 +8905,15 @@ void LLVOAvatar::updateFreezeCounter(S32 counter)  {  	if(counter)  	{ -		sFreezeCounter = counter ; +		sFreezeCounter = counter;  	}  	else if(sFreezeCounter > 0)  	{ -		sFreezeCounter-- ; +		sFreezeCounter--;  	}  	else  	{ -		sFreezeCounter = 0 ; +		sFreezeCounter = 0;  	}  } @@ -9989,7 +8965,7 @@ void LLVOAvatar::updateImpostors()  BOOL LLVOAvatar::isImpostor() const  { -	return (sUseImpostors && mUpdatePeriod >= VOAVATAR_IMPOSTOR_PERIOD) ? TRUE : FALSE; +	return (sUseImpostors && mUpdatePeriod >= IMPOSTOR_PERIOD) ? TRUE : FALSE;  } @@ -10018,7 +8994,7 @@ void LLVOAvatar::cacheImpostorValues()  	getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance);  } -void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) +void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const  {  	const LLVector3* ext = mDrawable->getSpatialExtents();  	extents[0] = ext[0]; @@ -10032,6 +9008,85 @@ void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& di  	angle.mV[2] = da;  } +void LLVOAvatar::idleUpdateRenderCost() +{ +	if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) +	{ +		return; +	} + +	U32 shame = 1; + +	std::set<LLUUID> textures; + +	attachment_map_t::const_iterator iter; +	for (iter = mAttachmentPoints.begin();  +		iter != mAttachmentPoints.end(); +		++iter) +	{ +		LLViewerJointAttachment* attachment = iter->second; +		LLViewerObject* object = attachment->getObject(); +		if (object && !object->isHUDAttachment()) +		{ +			LLDrawable* drawable = object->mDrawable; +			if (drawable) +			{ +				shame += 10; +				LLVOVolume* volume = drawable->getVOVolume(); +				if (volume) +				{ +					shame += calc_shame(volume, textures); +				} +			} +		} +	}	 + +	shame += textures.size() * 5; + +	setDebugText(llformat("%d", shame)); +	F32 green = 1.f-llclamp(((F32) shame-1024.f)/1024.f, 0.f, 1.f); +	F32 red = llmin((F32) shame/1024.f, 1.f); +	mText->setColor(LLColor4(red,green,0,1)); +} + +// static +BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index) +{ +	if (index < 0 || index >= TEX_NUM_INDICES) return false; +	return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsLocalTexture; +} + +// static +BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index) +{ +	if (index < 0 || index >= TEX_NUM_INDICES) return false; +	return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsBakedTexture; +} + +const std::string LLVOAvatar::getBakedStatusForPrintout() const +{ +	std::string line; + +	for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); +		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); +		 iter++) +	{ +		const ETextureIndex index = iter->first; +		const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second; +		if (text_dict->mIsBakedTexture) +		{ +			line += text_dict->mName; +			if (isTextureDefined(index)) +			{ +				line += "_baked"; +			} +			line += " "; +		} +	} +	return line; +} + +  U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures)  {  	if (!volume) @@ -10136,45 +9191,11 @@ U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures)  	return shame;  } -void LLVOAvatar::idleUpdateRenderCost() -{ -	if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) -	{ -		return; -	} - -	U32 shame = 1; - -	std::set<LLUUID> textures; - -	attachment_map_t::const_iterator iter; -	for (iter = mAttachmentPoints.begin();  -		iter != mAttachmentPoints.end(); -		++iter) -	{ -		LLViewerJointAttachment* attachment = iter->second; -		LLViewerObject* object = attachment->getObject(); -		if (object && !object->isHUDAttachment()) -		{ -			LLDrawable* drawable = object->mDrawable; -			if (drawable) -			{ -				shame += 10; -				LLVOVolume* volume = drawable->getVOVolume(); -				if (volume) -				{ -					shame += calc_shame(volume, textures); -				} -			} -		} -	}	 - -	shame += textures.size() * 5; +//----------------------------------------------------------------------------- +// Utility functions +//----------------------------------------------------------------------------- -	setDebugText(llformat("%d", shame)); -	F32 green = 1.f-llclamp(((F32) shame-1024.f)/1024.f, 0.f, 1.f); -	F32 red = llmin((F32) shame/1024.f, 1.f); -	mText->setColor(LLColor4(red,green,0,1)); +F32 calc_bouncy_animation(F32 x) +{ +	return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f;  } - - diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 14f7bd6dcc..bdb32319f8 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -1,4 +1,4 @@ -/**  +/**   * @file llvoavatar.h   * @brief Declaration of LLVOAvatar class which is a derivation fo   * LLViewerObject @@ -34,210 +34,40 @@  #ifndef LL_LLVOAVATAR_H  #define LL_LLVOAVATAR_H -// May help Visual Studio avoid opening this file. - -#include <set>  #include <map> -#include <algorithm>  #include <deque> +#include <string> +#include <vector>  #include "llchat.h"  #include "llviewerobject.h" -#include "lljointsolverrp3.h" +#include "llcharacter.h"  #include "llviewerjointmesh.h"  #include "llviewerjointattachment.h" -#include "llcharacter.h" -#include "material_codes.h" -#include "llanimationstates.h" -#include "v4coloru.h" -#include "llstring.h" -#include "llframetimer.h" -#include "llxmltree.h" -#include "llwearable.h"  #include "llrendertarget.h" +#include "llwearable.h" +#include "llvoavatardefines.h" + +extern const LLUUID ANIM_AGENT_BODY_NOISE; +extern const LLUUID ANIM_AGENT_BREATHE_ROT; +extern const LLUUID ANIM_AGENT_EDITING; +extern const LLUUID ANIM_AGENT_EYE; +extern const LLUUID ANIM_AGENT_FLY_ADJUST; +extern const LLUUID ANIM_AGENT_HAND_MOTION; +extern const LLUUID ANIM_AGENT_HEAD_ROT; +extern const LLUUID ANIM_AGENT_PELVIS_FIX; +extern const LLUUID ANIM_AGENT_TARGET; +extern const LLUUID ANIM_AGENT_WALK_ADJUST; -//Ventrella -//#include "llvoiceclient.h" -#include "llvoicevisualizer.h" -//End Ventrella - -const S32 VOAVATAR_SCRATCH_TEX_WIDTH = 512; -const S32 VOAVATAR_SCRATCH_TEX_HEIGHT = 512; -const S32 VOAVATAR_IMPOSTOR_PERIOD = 2; - -const LLUUID ANIM_AGENT_BODY_NOISE		=	LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise" -const LLUUID ANIM_AGENT_BREATHE_ROT	=	LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8");  //"breathe_rot" -const LLUUID ANIM_AGENT_EDITING		=	LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb");  //"editing" -const LLUUID ANIM_AGENT_EYE			=	LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea");  //"eye" -const LLUUID ANIM_AGENT_FLY_ADJUST		=	LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e");  //"fly_adjust" -const LLUUID ANIM_AGENT_HAND_MOTION	=	LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578");  //"hand_motion" -const LLUUID ANIM_AGENT_HEAD_ROT		=	LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d");  //"head_rot" -const LLUUID ANIM_AGENT_PELVIS_FIX		=	LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b");  //"pelvis_fix" -const LLUUID ANIM_AGENT_TARGET			=	LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55");  //"target" -const LLUUID ANIM_AGENT_WALK_ADJUST	=	LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d");  //"walk_adjust" - -class LLChat; -class LLXmlTreeNode;  class LLTexLayerSet; -class LLTexGlobalColor; -class LLTexGlobalColorInfo; -class LLTexLayerSetInfo; -class LLDriverParamInfo; - +class LLVoiceVisualizer;  class LLHUDText;  class LLHUDEffectSpiral; +class LLTexGlobalColor; -class LLVertexBufferAvatar : public LLVertexBuffer -{ -public: -	LLVertexBufferAvatar(); -	virtual void setupVertexBuffer(U32 data_mask) const; -}; - -typedef enum e_mesh_id -{ -	MESH_ID_HAIR, -	MESH_ID_HEAD, -	MESH_ID_UPPER_BODY, -	MESH_ID_LOWER_BODY, -	MESH_ID_SKIRT -} eMeshID; - -typedef enum e_render_name -{ -	RENDER_NAME_NEVER, -	RENDER_NAME_FADE, -	RENDER_NAME_ALWAYS -} eRenderName; - -const S32 BAKED_TEXTURE_COUNT = 5;  // number of values in ETextureIndex that are pre-composited - -//------------------------------------------------------------------------ -// LLVOAvatar Support classes -//------------------------------------------------------------------------ - -class LLVOAvatarBoneInfo -{ -	friend class LLVOAvatar; -	friend class LLVOAvatarSkeletonInfo; -public: -	LLVOAvatarBoneInfo() : mIsJoint(FALSE) {} -	~LLVOAvatarBoneInfo() -	{ -		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer()); -	} -	BOOL parseXml(LLXmlTreeNode* node); -	 -protected: -	std::string mName; -	BOOL mIsJoint; -	LLVector3 mPos; -	LLVector3 mRot; -	LLVector3 mScale; -	LLVector3 mPivot; -	typedef std::vector<LLVOAvatarBoneInfo*> child_list_t; -	child_list_t mChildList; -}; - -class LLVOAvatarSkeletonInfo -{ -	friend class LLVOAvatar; -public: -	LLVOAvatarSkeletonInfo() : -		mNumBones(0), mNumCollisionVolumes(0) {} -	~LLVOAvatarSkeletonInfo() -	{ -		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer()); -	} -	BOOL parseXml(LLXmlTreeNode* node); -	S32 getNumBones() { return mNumBones; } -	S32 getNumCollisionVolumes() { return mNumCollisionVolumes; } -	 -protected: -	S32 mNumBones; -	S32 mNumCollisionVolumes; -	typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t; -	bone_info_list_t mBoneInfoList; -}; - - -//------------------------------------------------------------------------ -// LLVOAvatarInfo -// One instance (in LLVOAvatar) with common data parsed from the XML files -//------------------------------------------------------------------------ -class LLVOAvatarInfo -{ -	friend class LLVOAvatar; -public: -	LLVOAvatarInfo(); -	~LLVOAvatarInfo(); -	 -protected: -	BOOL 	parseXmlSkeletonNode(LLXmlTreeNode* root); -	BOOL 	parseXmlMeshNodes(LLXmlTreeNode* root); -	BOOL 	parseXmlColorNodes(LLXmlTreeNode* root); -	BOOL 	parseXmlLayerNodes(LLXmlTreeNode* root); -	BOOL 	parseXmlDriverNodes(LLXmlTreeNode* root); -	 -	struct LLVOAvatarMeshInfo -	{ -		typedef std::pair<LLPolyMorphTargetInfo*,BOOL> morph_info_pair_t; -		typedef std::vector<morph_info_pair_t> morph_info_list_t; - -		LLVOAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {} -		~LLVOAvatarMeshInfo() -		{ -			morph_info_list_t::iterator iter; -			for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++) -			{ -				delete iter->first; -			} -			mPolyMorphTargetInfoList.clear(); -		} - -		std::string mType; -		S32			mLOD; -		std::string	mMeshFileName; -		std::string	mReferenceMeshName; -		F32			mMinPixelArea; -		morph_info_list_t mPolyMorphTargetInfoList; -	}; -	typedef std::vector<LLVOAvatarMeshInfo*> mesh_info_list_t; -	mesh_info_list_t mMeshInfoList; - -	typedef std::vector<LLPolySkeletalDistortionInfo*> skeletal_distortion_info_list_t; -	skeletal_distortion_info_list_t mSkeletalDistortionInfoList; -	 -	struct LLVOAvatarAttachmentInfo -	{ -		LLVOAvatarAttachmentInfo() -			: mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE), -			  mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {} -		std::string mName; -		std::string mJointName; -		LLVector3 mPosition; -		LLVector3 mRotationEuler; -		S32 mGroup; -		S32 mAttachmentID; -		S32 mPieMenuSlice; -		BOOL mVisibleFirstPerson; -		BOOL mIsHUDAttachment; -		BOOL mHasPosition; -		BOOL mHasRotation; -	}; -	typedef std::vector<LLVOAvatarAttachmentInfo*> attachment_info_list_t; -	attachment_info_list_t mAttachmentInfoList; -	 -	LLTexGlobalColorInfo *mTexSkinColorInfo; -	LLTexGlobalColorInfo *mTexHairColorInfo; -	LLTexGlobalColorInfo *mTexEyeColorInfo; - -	typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t; -	layer_info_list_t mLayerInfoList; - -	typedef std::vector<LLDriverParamInfo*> driver_info_list_t; -	driver_info_list_t mDriverInfoList; -}; +class LLVOAvatarBoneInfo; +class LLVOAvatarSkeletonInfo; +class LLVOAvatarXmlInfo;  //------------------------------------------------------------------------  // LLVOAvatar @@ -246,44 +76,28 @@ class LLVOAvatar :  	public LLViewerObject,  	public LLCharacter  { -protected:	 +protected:  	virtual ~LLVOAvatar();  public: - -	struct CompareScreenAreaGreater -	{		 -		bool operator()(const LLCharacter* const& lhs, const LLCharacter* const& rhs) -		{ -			return lhs->getPixelArea() > rhs->getPixelArea(); -		} -	}; - -	enum  -	{ -		VERTEX_DATA_MASK =	(1 << LLVertexBuffer::TYPE_VERTEX) | -							(1 << LLVertexBuffer::TYPE_NORMAL) | -							(1 << LLVertexBuffer::TYPE_TEXCOORD0) | -							(1 << LLVertexBuffer::TYPE_WEIGHT) | -							(1 << LLVertexBuffer::TYPE_CLOTHWEIGHT)							 -	}; -  	LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);  	/*virtual*/ void markDead(); +	void startDefaultMotions();  	static void updateImpostors();  	//--------------------------------------------------------------------  	// LLViewerObject interface  	//-------------------------------------------------------------------- -	static void initClass();	// Initialize data that's only inited once per class. -	static void cleanupClass();	// Cleanup data that's only inited once per class. +public: +	static void initClass(); // Initialize data that's only init'd once per class. +	static void cleanupClass();	// Cleanup data that's only init'd once per class.  	static BOOL parseSkeletonFile(const std::string& filename); -	virtual U32 processUpdateMessage(	LLMessageSystem *mesgsys, -										void **user_data, -										U32 block_num, -										const EObjectUpdateType update_type, -										LLDataPacker *dp); +	virtual U32 processUpdateMessage(LLMessageSystem *mesgsys, +									 void **user_data, +									 U32 block_num, +									 const EObjectUpdateType update_type, +									 LLDataPacker *dp);  	/*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);  	void idleUpdateVoiceVisualizer(bool voice_enabled);  	void idleUpdateMisc(bool detailed_update); @@ -296,12 +110,11 @@ public:  	void idleUpdateTractorBeam();  	void idleUpdateBelowWater(); +public:  	virtual BOOL updateLOD(); -	void setFootPlane(const LLVector4 &plane) { mFootPlane = plane; } -	/*virtual*/ BOOL    isActive() const; // Whether this object needs to do an idleUpdate. +	/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.  	// Graphical stuff for objects - maybe broken out into render class later? -  	U32 renderFootShadows();  	U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255));  	U32 renderRigid(); @@ -310,13 +123,13 @@ public:  	void renderCollisionVolumes();  	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, -									  S32 face = -1,                          // which face to check, -1 = ALL_SIDES -									  BOOL pick_transparent = FALSE, -									  S32* face_hit = NULL,                   // which face was hit -									  LLVector3* intersection = NULL,         // return the intersection point -									  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -									  LLVector3* normal = NULL,               // return the surface normal at the intersection point -									  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +										  S32 face = -1,                          // which face to check, -1 = ALL_SIDES +										  BOOL pick_transparent = FALSE, +										  S32* face_hit = NULL,                   // which face was hit +										  LLVector3* intersection = NULL,         // return the intersection point +										  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point +										  LLVector3* normal = NULL,               // return the surface normal at the intersection point +										  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point  		);  	/*virtual*/ void updateTextures(LLAgent &agent); @@ -328,19 +141,18 @@ public:  	void updateVisibility();  	void updateAttachmentVisibility(U32 camera_mode);  	void clampAttachmentPositions(); -	S32 getAttachmentCount();	// Warning: order(N) not order(1) +	S32 getAttachmentCount(); // Warning: order(N) not order(1) -	BOOL hasHUDAttachment(); -	LLBBox getHUDBBox(); -// 	void renderHUD(BOOL for_select); // old +	// HUD functions +	BOOL hasHUDAttachment() const; +	LLBBox getHUDBBox() const;  	void rebuildHUD();  	/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); -	/*virtual*/ BOOL		updateGeometry(LLDrawable *drawable); -	void updateShadowFaces(); +	/*virtual*/ BOOL updateGeometry(LLDrawable *drawable); -	/*virtual*/ void		setPixelAreaAndAngle(LLAgent &agent); -	BOOL					updateJointLODs(); +	/*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); +	BOOL updateJointLODs();  	virtual void updateRegion(LLViewerRegion *regionp); @@ -352,57 +164,14 @@ public:  	BOOL needsImpostorUpdate() const;  	const LLVector3& getImpostorOffset() const;  	const LLVector2& getImpostorDim() const; -	void getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance); +	void getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const;  	void cacheImpostorValues();  	void setImpostorDim(const LLVector2& dim);  	//-------------------------------------------------------------------- -	// texture entry assignment -	//-------------------------------------------------------------------- -	enum ETextureIndex -	{ -		TEX_HEAD_BODYPAINT = 0, -		TEX_UPPER_SHIRT = 1, -		TEX_LOWER_PANTS = 2, -		TEX_EYES_IRIS = 3, -		TEX_HAIR = 4, -		TEX_UPPER_BODYPAINT = 5, -		TEX_LOWER_BODYPAINT = 6, -		TEX_LOWER_SHOES = 7, -		TEX_HEAD_BAKED = 8,			// Pre-composited -		TEX_UPPER_BAKED = 9,		// Pre-composited -		TEX_LOWER_BAKED = 10,		// Pre-composited -		TEX_EYES_BAKED = 11,		// Pre-composited -		TEX_LOWER_SOCKS = 12, -		TEX_UPPER_JACKET = 13, -		TEX_LOWER_JACKET = 14, -		TEX_UPPER_GLOVES = 15, -		TEX_UPPER_UNDERSHIRT = 16, -		TEX_LOWER_UNDERPANTS = 17, -		TEX_SKIRT = 18, -		TEX_SKIRT_BAKED = 19,		// Pre-composited -		TEX_NUM_ENTRIES = 20 -	}; -	// Note: if TEX_NUM_ENTRIES changes, update AGENT_TEXTURES in llagentinfo.h, mTextureIndexBaked, and BAKED_TEXTURE_COUNT - -	static BOOL isTextureIndexBaked( S32 i ) -		{ -			switch(i) -			{ -			case TEX_HEAD_BAKED: -			case TEX_UPPER_BAKED: -			case TEX_LOWER_BAKED: -			case TEX_EYES_BAKED: -			case TEX_SKIRT_BAKED: -				return TRUE; -			default: -				return FALSE; -			} -		} - -	//--------------------------------------------------------------------  	// LLCharacter interface  	//-------------------------------------------------------------------- +public:  	virtual const char *getAnimationPrefix() { return "avatar"; }  	virtual LLJoint *getRootJoint() { return &mRoot; }  	virtual LLVector3 getCharacterPosition(); @@ -417,8 +186,8 @@ public:  	virtual F32 getPixelArea() const;  	virtual LLPolyMesh*	getHeadMesh();  	virtual LLPolyMesh*	getUpperBodyMesh(); -	virtual LLVector3d	getPosGlobalFromAgent(const LLVector3 &position); -	virtual LLVector3	getPosAgentFromGlobal(const LLVector3d &position); +	virtual LLVector3d getPosGlobalFromAgent(const LLVector3 &position); +	virtual LLVector3 getPosAgentFromGlobal(const LLVector3d &position);  	virtual void updateVisualParams();  	virtual BOOL startMotion(const LLUUID& id, F32 time_offset = 0.f);  	virtual BOOL stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE); @@ -433,30 +202,35 @@ public:  	//--------------------------------------------------------------------  	// Other public functions  	//-------------------------------------------------------------------- -	BOOL			allocateCollisionVolumes( U32 num ); -	void			resetHUDAttachments(); -	static void		getAnimLabels( LLDynamicArray<std::string>* labels ); -	static void		getAnimNames( LLDynamicArray<std::string>* names ); - +public:  	static void		onCustomizeStart();  	static void		onCustomizeEnd(); -	void			getLocalTextureByteCount( S32* gl_byte_count ); +public:  	static void		dumpTotalLocalTextureByteCount(); +protected: +	void			getLocalTextureByteCount( S32* gl_byte_count ); + +public:  	LLMotion*		findMotion(const LLUUID& id);  	BOOL			isVisible(); -	BOOL			isSelf() { return mIsSelf; } -	BOOL			isCulled() { return mCulled; } -	 -	S32				getUnbakedPixelAreaRank(); -	void			setVisibilityRank(U32 rank); -	U32				getVisibilityRank(); +	BOOL			isSelf() const { return mIsSelf; } +	BOOL			isCulled() const { return mCulled; } + +public:  	static void		cullAvatarsByPixelArea(); +	void			setVisibilityRank(U32 rank);  +	U32				getVisibilityRank(); // unused +protected: +	S32				getUnbakedPixelAreaRank(); +public:  	void			dumpLocalTextures(); -	const LLUUID&	grabLocalTexture(ETextureIndex index); -	BOOL			canGrabLocalTexture(ETextureIndex index); +	const LLUUID&	grabLocalTexture(LLVOAvatarDefines::ETextureIndex index); +	BOOL			canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex index); +	BOOL            isTextureDefined(U8 te) const; +	BOOL			isTextureVisible(U8 te) const;  	void			startAppearanceAnimation(BOOL set_by_user, BOOL play_sound);  	void			setCompositeUpdatesEnabled(BOOL b); @@ -469,46 +243,31 @@ public:  	// Returns "FirstName LastName"  	std::string		getFullname() const; -	//-------------------------------------------------------------------- -	// internal (pseudo-private) functions -	//-------------------------------------------------------------------- -	F32 getPelvisToFoot() { return mPelvisToFoot; } -	 -	void startDefaultMotions(); -	void buildCharacter(); -	void releaseMeshData(); -	void restoreMeshData(); -	void updateMeshData(); - -	void computeBodySize(); -  	BOOL updateCharacter(LLAgent &agent);  	void updateHeadOffset(); -	LLUUID& getStepSound(); +	F32 getPelvisToFoot() const { return mPelvisToFoot; } + +public: +	BOOL isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims);  	void processAnimationStateChanges(); +protected:  	BOOL processSingleAnimationStateChange(const LLUUID &anim_id, BOOL start);  	void resetAnimations(); -	BOOL isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims); -	BOOL needsRenderBeam(); - -	// Utility functions +public:  	void resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm);  	void resolveHeightAgent(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);  	void resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm); - +	  	void slamPosition(); // Slam position to transmitted position (for teleport); -	BOOL loadAvatar(); -	BOOL setupBone(LLVOAvatarBoneInfo* info, LLViewerJoint* parent); -	BOOL buildSkeleton(LLVOAvatarSkeletonInfo *info); -  	// morph targets and such  	void processAvatarAppearance( LLMessageSystem* mesgsys );  	void onFirstTEMessageReceived();  	void updateSexDependentLayerSets( BOOL set_by_user );  	void dirtyMesh(); // Dirty the avatar mesh +	void hideSkirt();  	virtual void setParent(LLViewerObject* parent);  	virtual void addChild(LLViewerObject *childp); @@ -531,410 +290,309 @@ public:  	void			updateMeshTextures();  	//-------------------------------------------------------------------- -	// local textures for compositing. -	//-------------------------------------------------------------------- -	enum ELocTexIndex -	{ -		LOCTEX_UPPER_SHIRT = 0, -		LOCTEX_UPPER_BODYPAINT = 1, -		LOCTEX_LOWER_PANTS = 2, -		LOCTEX_LOWER_BODYPAINT = 3, -		LOCTEX_HEAD_BODYPAINT = 4, -		LOCTEX_LOWER_SHOES = 5, -		LOCTEX_LOWER_SOCKS = 6, -		LOCTEX_UPPER_JACKET = 7, -		LOCTEX_LOWER_JACKET = 8, -		LOCTEX_UPPER_GLOVES = 9, -		LOCTEX_UPPER_UNDERSHIRT = 10, -		LOCTEX_LOWER_UNDERPANTS = 11, -		LOCTEX_EYES_IRIS = 12, -		LOCTEX_SKIRT = 13, -		LOCTEX_NUM_ENTRIES = 14 -	}; - -	//--------------------------------------------------------------------  	// texture compositing (used only by the LLTexLayer series of classes)  	//-------------------------------------------------------------------- +public:  	LLColor4		getGlobalColor( const std::string& color_name );  	BOOL			isLocalTextureDataAvailable( LLTexLayerSet* layerset );  	BOOL			isLocalTextureDataFinal( LLTexLayerSet* layerset ); -	ETextureIndex	getBakedTE( LLTexLayerSet* layerset ); +	LLVOAvatarDefines::ETextureIndex	getBakedTE( LLTexLayerSet* layerset );  	void			updateComposites();  	void			onGlobalColorChanged( LLTexGlobalColor* global_color, BOOL set_by_user ); -	BOOL			getLocalTextureRaw( S32 index, LLImageRaw* image_raw_pp ); -	BOOL			getLocalTextureGL( S32 index, LLImageGL** image_gl_pp ); -	const LLUUID&	getLocalTextureID( S32 index ); +	BOOL			getLocalTextureRaw( LLVOAvatarDefines::ETextureIndex index, LLImageRaw* image_raw_pp ); +	BOOL			getLocalTextureGL( LLVOAvatarDefines::ETextureIndex index, LLImageGL** image_gl_pp ); +	const LLUUID&	getLocalTextureID( LLVOAvatarDefines::ETextureIndex index );  	LLGLuint		getScratchTexName( LLGLenum format, U32* texture_bytes );  	BOOL			bindScratchTexture( LLGLenum format );  	void			invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user ); +	void			invalidateAll();  	void			forceBakeAllTextures(bool slam_for_debug = false);  	static void		processRebakeAvatarTextures(LLMessageSystem* msg, void**); -	void			setNewBakedTexture( ETextureIndex i, const LLUUID& uuid ); -	void			setCachedBakedTexture( ETextureIndex i, const LLUUID& uuid ); +	void			setNewBakedTexture( LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid ); +	void			setCachedBakedTexture( LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid ); +	void			releaseUnnecessaryTextures();  	void			requestLayerSetUploads();  	bool			hasPendingBakedUploads();  	static void		onLocalTextureLoaded( BOOL succcess, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );  	static void		dumpArchetypeXML( void* );  	static void		dumpScratchTextureByteCount();  	static void		dumpBakedStatus(); -	static void		deleteCachedImages(); +	static void		deleteCachedImages(bool clearAll=true);  	static void		destroyGL();  	static void		restoreGL();  	static void		resetImpostors(); -	static enum EWearableType	getTEWearableType( S32 te ); -	static LLUUID			getDefaultTEImageID( S32 te ); +	static enum EWearableType	getTEWearableType(LLVOAvatarDefines::ETextureIndex te ); +	static LLUUID			getDefaultTEImageID(LLVOAvatarDefines::ETextureIndex te ); +	static void		onChangeSelfInvisible(BOOL newvalue); +	void			setInvisible(BOOL newvalue); + +  	//--------------------------------------------------------------------  	// Clothing colors (conventience functions to access visual parameters  	//-------------------------------------------------------------------- -	void			setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL set_by_user ); -	LLColor4		getClothesColor( ETextureIndex te ); -	BOOL			teToColorParams( ETextureIndex te, const char* param_name[3] ); +public: +	void			setClothesColor( LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL set_by_user ); +	LLColor4		getClothesColor( LLVOAvatarDefines::ETextureIndex te ); +	BOOL			teToColorParams( LLVOAvatarDefines::ETextureIndex te, const char* param_name[3] );  	BOOL			isWearingWearableType( EWearableType type );  	//--------------------------------------------------------------------  	// texture compositing  	//-------------------------------------------------------------------- +public:  	void			setLocTexTE( U8 te, LLViewerImage* image, BOOL set_by_user );  	void			setupComposites();  	//-------------------------------------------------------------------- -	// member variables -	//-------------------------------------------------------------------- - -	BOOL mDirtyMesh; - -	LLFace *mShadow0Facep; -	LLFace *mShadow1Facep; - -	LLFrameTimer mUpdateLODTimer; // controls frequency of LOD change calculations -	 -	//-------------------------------------------------------------------- -	// State of deferred character building +	// Handling partially loaded avatars (Ruth)  	//-------------------------------------------------------------------- -	BOOL mIsBuilt; +public: +	BOOL            isFullyLoaded(); +	BOOL            updateIsFullyLoaded(); +private: +	BOOL            mFullyLoaded; +	BOOL            mPreviousFullyLoaded; +	BOOL            mFullyLoadedInitialized; +	S32             mFullyLoadedFrameCounter; +	LLFrameTimer    mFullyLoadedTimer;  	//-------------------------------------------------------------------- -	// skeleton for skinned avatar +	// Collision Volumes  	//-------------------------------------------------------------------- -	S32				mNumJoints; -	LLViewerJoint	*mSkeleton; - +public:  	S32								mNumCollisionVolumes;  	LLViewerJointCollisionVolume*	mCollisionVolumes;  	//--------------------------------------------------------------------  	// cached pointers to well known joints  	//-------------------------------------------------------------------- -	LLViewerJoint *mPelvisp; -	LLViewerJoint *mTorsop; -	LLViewerJoint *mChestp; -	LLViewerJoint *mNeckp; -	LLViewerJoint *mHeadp; -	LLViewerJoint *mSkullp; -	LLViewerJoint *mEyeLeftp; -	LLViewerJoint *mEyeRightp; -	LLViewerJoint *mHipLeftp; -	LLViewerJoint *mHipRightp; -	LLViewerJoint *mKneeLeftp; -	LLViewerJoint *mKneeRightp; -	LLViewerJoint *mAnkleLeftp; -	LLViewerJoint *mAnkleRightp; -	LLViewerJoint *mFootLeftp; -	LLViewerJoint *mFootRightp; -	LLViewerJoint *mWristLeftp; -	LLViewerJoint *mWristRightp; - -	//-------------------------------------------------------------------- -	// special purpose joint for HUD attachments -	//-------------------------------------------------------------------- -	LLViewerJoint *mScreenp; - -	//-------------------------------------------------------------------- -	// mesh objects for skinned avatar -	//-------------------------------------------------------------------- -	LLViewerJoint		mHairLOD; -	LLViewerJointMesh		mHairMesh0; -	LLViewerJointMesh		mHairMesh1; -	LLViewerJointMesh		mHairMesh2; -	LLViewerJointMesh		mHairMesh3; -	LLViewerJointMesh		mHairMesh4; -	LLViewerJointMesh		mHairMesh5; - -	LLViewerJoint		mHeadLOD; -	LLViewerJointMesh		mHeadMesh0; -	LLViewerJointMesh		mHeadMesh1; -	LLViewerJointMesh		mHeadMesh2; -	LLViewerJointMesh		mHeadMesh3; -	LLViewerJointMesh		mHeadMesh4; - -	LLViewerJoint		mEyeLashLOD; -	LLViewerJointMesh		mEyeLashMesh0; - -	LLViewerJoint		mUpperBodyLOD; -	LLViewerJointMesh		mUpperBodyMesh0; -	LLViewerJointMesh		mUpperBodyMesh1; -	LLViewerJointMesh		mUpperBodyMesh2; -	LLViewerJointMesh		mUpperBodyMesh3; -	LLViewerJointMesh		mUpperBodyMesh4; - -	LLViewerJoint		mLowerBodyLOD; -	LLViewerJointMesh		mLowerBodyMesh0; -	LLViewerJointMesh		mLowerBodyMesh1; -	LLViewerJointMesh		mLowerBodyMesh2; -	LLViewerJointMesh		mLowerBodyMesh3; -	LLViewerJointMesh		mLowerBodyMesh4; - -	LLViewerJoint		mEyeBallLeftLOD; -	LLViewerJointMesh		mEyeBallLeftMesh0; -	LLViewerJointMesh		mEyeBallLeftMesh1; - -	LLViewerJoint		mEyeBallRightLOD; -	LLViewerJointMesh		mEyeBallRightMesh0; -	LLViewerJointMesh		mEyeBallRightMesh1; - -	LLViewerJoint		mSkirtLOD; -	LLViewerJointMesh		mSkirtMesh0; -	LLViewerJointMesh		mSkirtMesh1; -	LLViewerJointMesh		mSkirtMesh2; -	LLViewerJointMesh		mSkirtMesh3; -	LLViewerJointMesh		mSkirtMesh4; - -	typedef std::multimap<std::string, LLPolyMesh*> mesh_map_t; -	mesh_map_t				mMeshes; - -	S32                 mNumInitFaces ; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer. -	//-------------------------------------------------------------------- -	// true if this avatar is for this viewers agent -	//-------------------------------------------------------------------- -	BOOL			mIsSelf; - -	//-------------------------------------------------------------------- -	// texture ids and pointers -	//-------------------------------------------------------------------- -	LLPointer<LLViewerImage> mShadowImagep; - -	LLUUID			mLastHeadBakedID; -	LLUUID			mLastUpperBodyBakedID; -	LLUUID			mLastLowerBodyBakedID; -	LLUUID			mLastEyesBakedID; -	LLUUID			mLastSkirtBakedID; +public: +	LLViewerJoint* mPelvisp; +	LLViewerJoint* mTorsop; +	LLViewerJoint* mChestp; +	LLViewerJoint* mNeckp; +	LLViewerJoint* mHeadp; +	LLViewerJoint* mSkullp; +	LLViewerJoint* mEyeLeftp; +	LLViewerJoint* mEyeRightp; +	LLViewerJoint* mHipLeftp; +	LLViewerJoint* mHipRightp; +	LLViewerJoint* mKneeLeftp; +	LLViewerJoint* mKneeRightp; +	LLViewerJoint* mAnkleLeftp; +	LLViewerJoint* mAnkleRightp; +	LLViewerJoint* mFootLeftp; +	LLViewerJoint* mFootRightp; +	LLViewerJoint* mWristLeftp; +	LLViewerJoint* mWristRightp;  	//--------------------------------------------------------------------  	// impostor state  	//-------------------------------------------------------------------- +public:  	LLRenderTarget	mImpostor; +	BOOL			mNeedsImpostorUpdate; +private:  	LLVector3		mImpostorOffset;  	LLVector2		mImpostorDim; -	BOOL			mNeedsImpostorUpdate;  	BOOL			mNeedsAnimUpdate;  	LLVector3		mImpostorExtents[2];  	LLVector3		mImpostorAngle;  	F32				mImpostorDistance;  	F32				mImpostorPixelArea;  	LLVector3		mLastAnimExtents[2];   -	 +  	//--------------------------------------------------------------------  	// Misc Render State  	//-------------------------------------------------------------------- +public:  	BOOL			mIsDummy; // For special views  	S32				mSpecialRenderMode; // Special lighting  	//-------------------------------------------------------------------- -	// Animation timer -	//-------------------------------------------------------------------- -	LLTimer		mAnimTimer; -	F32			mTimeLast; - -	//-------------------------------------------------------------------- -	// Measures speed (for diagnostics mostly). -	//-------------------------------------------------------------------- -	F32 mSpeedAccum; - -	//--------------------------------------------------------------------  	// animation state data  	//-------------------------------------------------------------------- +public:  	typedef std::map<LLUUID, S32>::iterator AnimIterator; -	std::map<LLUUID, S32> mSignaledAnimations;		// requested state of Animation name/value -	std::map<LLUUID, S32> mPlayingAnimations;		// current state of Animation name/value +	std::map<LLUUID, S32> mSignaledAnimations; // requested state of Animation name/value +	std::map<LLUUID, S32> mPlayingAnimations; // current state of Animation name/value  	typedef std::multimap<LLUUID, LLUUID> AnimationSourceMap;  	typedef AnimationSourceMap::iterator AnimSourceIterator; -	AnimationSourceMap mAnimationSources;	// object ids that triggered anim ids - -	BOOL				mTurning;		// controls hysteresis on avatar rotation - -	//-------------------------------------------------------------------- -	// misc. animation related state -	//-------------------------------------------------------------------- -	F32				mSpeed; +	AnimationSourceMap mAnimationSources; // object ids that triggered anim ids  	//-------------------------------------------------------------------- -	// Shadow stuff +	// Shadowing  	//-------------------------------------------------------------------- +public: +	void updateShadowFaces();  	LLDrawable*		mShadow; -	BOOL			mInAir; -	LLFrameTimer	mTimeInAir; +private: +	LLFace* mShadow0Facep; +	LLFace* mShadow1Facep; +	LLPointer<LLViewerImage> mShadowImagep;  	//--------------------------------------------------------------------  	// Keeps track of foot step state for generating sounds  	//-------------------------------------------------------------------- +public: +	void setFootPlane(const LLVector4 &plane) { mFootPlane = plane; } +	LLVector4		mFootPlane; +private:  	BOOL			mWasOnGroundLeft;  	BOOL			mWasOnGroundRight; -	LLVector4		mFootPlane; - -	//-------------------------------------------------------------------- -	// Keep track of the material being stepped on -	//-------------------------------------------------------------------- -	BOOL			mStepOnLand; -	U8				mStepMaterial; -	LLVector3		mStepObjectVelocity;  	//--------------------------------------------------------------------  	// Pelvis height adjustment members.  	//-------------------------------------------------------------------- -	F32				mPelvisToFoot; +public:  	LLVector3		mBodySize;  	S32				mLastSkeletonSerialNum; - -	//-------------------------------------------------------------------- -	// current head position -	//-------------------------------------------------------------------- -	LLVector3		mHeadOffset; - -	//-------------------------------------------------------------------- -	// avatar skeleton -	//-------------------------------------------------------------------- -	LLViewerJoint	mRoot; - -	//-------------------------------------------------------------------- -	// sitting state -	//-------------------------------------------------------------------- -	BOOL			mIsSitting; +private: +	F32				mPelvisToFoot;  	//--------------------------------------------------------------------  	// Display the name, then optionally fade it out  	//-------------------------------------------------------------------- -	LLFrameTimer				mTimeVisible; +public: +	LLFrameTimer				mChatTimer;  	LLPointer<LLHUDText>		mNameText; +private: +	LLFrameTimer				mTimeVisible;  	std::deque<LLChat>			mChats; -	LLFrameTimer				mChatTimer;  	BOOL						mTyping;  	LLFrameTimer				mTypingTimer;  	//-------------------------------------------------------------------- -	// destroy mesh data after being invisible for a while -	//-------------------------------------------------------------------- -	BOOL			mMeshValid; -	BOOL			mVisible; -	LLFrameTimer	mMeshInvisibleTime; - -	//--------------------------------------------------------------------  	// wind rippling in clothes  	//-------------------------------------------------------------------- +public:  	LLVector4		mWindVec; -	F32				mWindFreq;  	F32				mRipplePhase; +	BOOL			mBelowWater; +private: +	F32				mWindFreq;  	LLFrameTimer	mRippleTimer;  	F32				mRippleTimeLast;  	LLVector3		mRippleAccel;  	LLVector3		mLastVel; -	BOOL			mBelowWater;  	//--------------------------------------------------------------------  	// appearance morphing  	//-------------------------------------------------------------------- +public: +	BOOL			mAppearanceAnimating; +private:  	LLFrameTimer	mAppearanceMorphTimer;  	BOOL			mAppearanceAnimSetByUser;  	F32				mLastAppearanceBlendTime; -	BOOL			mAppearanceAnimating; - -	//-------------------------------------------------------------------- -	// we're morphing for lip sync -	//-------------------------------------------------------------------- -	bool					mLipSyncActive;  	//-------------------------------------------------------------------- -	// cached pointers morphs for lip sync +	// Attachments  	//-------------------------------------------------------------------- -	LLVisualParam		   *mOohMorph; -	LLVisualParam		   *mAahMorph; +public: +	// map of attachment points, by ID +	typedef std::map<S32, LLViewerJointAttachment*> attachment_map_t; +	attachment_map_t mAttachmentPoints; +	std::vector<LLPointer<LLViewerObject> > mPendingAttachment;  	//-------------------------------------------------------------------- -	// static members +	// static preferences that are controlled by user settings/menus  	//-------------------------------------------------------------------- +public: +	static S32		sRenderName; +	static BOOL		sRenderGroupTitles;  	static S32		sMaxVisible;  	static F32		sRenderDistance; //distance at which avatars will render (affected by control "RenderAvatarMaxVisible") -	static S32		sCurJoint; -	static S32		sCurVolume;  	static BOOL		sShowAnimationDebug; // show animation debug info  	static BOOL		sUseImpostors; //use impostors for far away avatars  	static BOOL		sShowFootPlane;	// show foot collision plane reported by server  	static BOOL		sShowCollisionVolumes;	// show skeletal collision volumes  	static BOOL		sVisibleInFirstPerson; -	static S32		sMaxOtherAvatarsToComposite; -  	static S32		sNumLODChangesThisFrame; - -	// global table of sound ids per material, and the ground -	static LLUUID	sStepSounds[LL_MCODE_END]; -	static LLUUID	sStepSoundOnLand; - -	static S32		sRenderName; -	static BOOL		sRenderGroupTitles;  	static S32		sNumVisibleChatBubbles;  	static BOOL		sDebugInvisible;  	static BOOL		sShowAttachmentPoints; +	static F32		sLODFactor; // user-settable LOD factor +	static BOOL		sJointDebug; // output total number of joints being touched for each avatar +	static BOOL     sDebugAvatarRotation; + +	static S32 sNumVisibleAvatars; // Number of instances of this class +	 +	//-------------------------------------------------------------------- +	// Miscellaneous public variables. +	//-------------------------------------------------------------------- +public: +	BOOL			mInAir; +	LLFrameTimer	mTimeInAir; +	LLVector3 mHeadOffset; // current head position +	LLViewerJoint mRoot; // avatar skeleton +	BOOL mIsSitting; // sitting state + +	//-------------------------------------------------------------------- +	// Private member variables. +	//-------------------------------------------------------------------- +private: +	BOOL mIsSelf; // True if this avatar is for this viewer's agent + +	LLViewerJoint *mScreenp; // special purpose joint for HUD attachments +	BOOL mIsBuilt; // state of deferred character building +	F32 mSpeedAccum; // measures speed (for diagnostics mostly). + +	 +	// LLFrameTimer mUpdateLODTimer; // controls frequency of LOD change calculations +	BOOL mDirtyMesh; +	BOOL mTurning; // controls hysteresis on avatar rotation +	F32	mSpeed; // misc. animation repeated state -	// Number of instances of this class -	static S32		sNumVisibleAvatars; +	// Keep track of the material being stepped on +	BOOL mStepOnLand; +	U8 mStepMaterial; +	LLVector3 mStepObjectVelocity; + +	// Destroy mesh data after being invisible for a while +	BOOL			mMeshValid; +	BOOL			mVisible; +	LLFrameTimer	mMeshInvisibleTime; + +	// Lip synch morph stuff +	bool mLipSyncActive; // we're morphing for lip sync +	LLVisualParam* mOohMorph; // cached pointers morphs for lip sync +	LLVisualParam* mAahMorph; // cached pointers morphs for lip sync + +	// Skeleton for skinned avatar +	S32				mNumJoints; +	LLViewerJoint*	mSkeleton;  	// Scratch textures used for compositing  	static LLMap< LLGLenum, LLGLuint*> sScratchTexNames;  	static LLMap< LLGLenum, F32*> sScratchTexLastBindTime;  	static S32 sScratchTexBytes; -	// map of attachment points, by ID -	typedef std::map<S32, LLViewerJointAttachment*> attachment_map_t; -	attachment_map_t mAttachmentPoints; +	// Global table of sound ids per material, and the ground +	const static LLUUID	sStepSounds[LL_MCODE_END]; +	const static LLUUID	sStepSoundOnLand; -	std::vector<LLPointer<LLViewerObject> > mPendingAttachment; - -	// xml parse tree of avatar config file +	// Xml parse tree of avatar config file  	static LLXmlTree sXMLTree; -	// xml parse tree of avatar skeleton file +	// Xml parse tree of avatar skeleton file  	static LLXmlTree sSkeletonXMLTree; -	// user-settable LOD factor -	static F32		sLODFactor; - -	// output total number of joints being touched for each avatar -	static BOOL		sJointDebug; -	static ETextureIndex sBakedTextureIndices[BAKED_TEXTURE_COUNT]; - -	static F32 		sUnbakedTime; // Total seconds with >=1 unbaked avatars -	static F32 		sUnbakedUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)  -	static F32 		sGreyTime; // Total seconds with >=1 grey avatars -	static F32 		sGreyUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)  +	// Voice Visualizer is responsible for detecting the user's voice signal, and when the +	// user speaks, it puts a voice symbol over the avatar's head, and triggering gesticulations +	LLVoiceVisualizer*  mVoiceVisualizer; +	int					mCurrentGesticulationLevel; -	//-------------------------------------------------------------------- -	// Texture Layer Sets and Global Colors -	//--------------------------------------------------------------------	 -	LLTexLayerSet*		mHeadLayerSet; -	LLTexLayerSet*		mUpperBodyLayerSet; -	LLTexLayerSet*		mLowerBodyLayerSet; -	LLTexLayerSet*		mEyesLayerSet; -	LLTexLayerSet*		mSkirtLayerSet; - +	// Animation timer +	LLTimer		mAnimTimer; +	F32			mTimeLast;	 -protected:  	LLPointer<LLHUDEffectSpiral> mBeam;  	LLFrameTimer mBeamTimer; -	LLFrameTimer mEditEffectTimer; -	F32		mRenderPriority;  	F32		mAdjustedPixelArea;  	LLWString mNameString; @@ -954,27 +612,11 @@ protected:  	//--------------------------------------------------------------------  	// local textures for compositing.  	//-------------------------------------------------------------------- - -	LLPointer<LLViewerImage> mLocalTexture[ LOCTEX_NUM_ENTRIES ]; -	BOOL 				mLocalTextureBaked[ LOCTEX_NUM_ENTRIES ]; // Texture is covered by a baked texture -	S32 				mLocalTextureDiscard[ LOCTEX_NUM_ENTRIES ]; -	LLUUID				mSavedTE[ TEX_NUM_ENTRIES ]; +private: +	LLUUID				mSavedTE[ LLVOAvatarDefines::TEX_NUM_INDICES ];  	BOOL				mFirstTEMessageReceived;  	BOOL				mFirstAppearanceMessageReceived; - -	BOOL				mHeadBakedLoaded; -	S32					mHeadMaskDiscard; -	BOOL				mUpperBakedLoaded; -	S32					mUpperMaskDiscard; -	BOOL				mLowerBakedLoaded; -	S32					mLowerMaskDiscard; -	BOOL				mEyesBakedLoaded; -	BOOL				mSkirtBakedLoaded; - -	//RN: testing 2 pass rendering -	U32					mHeadMaskTexName; -	U32					mUpperMaskTexName; -	U32					mLowerMaskTexName; +	BOOL				mHasBakedHair;  	BOOL				mCulled;  	U32					mVisibilityRank; @@ -985,6 +627,7 @@ protected:  	//--------------------------------------------------------------------  	// Global Colors  	//-------------------------------------------------------------------- +private:  	LLTexGlobalColor*	mTexSkinColor;  	LLTexGlobalColor*	mTexHairColor;  	LLTexGlobalColor*	mTexEyeColor; @@ -992,61 +635,127 @@ protected:  	BOOL				mNeedsSkin;  //if TRUE, avatar has been animated and verts have not been updated  	S32					mUpdatePeriod; -	static LLVOAvatarSkeletonInfo*	sSkeletonInfo; -	static LLVOAvatarInfo*			sAvatarInfo; - -	  	//-------------------------------------------------------------------- -	// Handling partially loaded avatars (Ruth) +	// Internal functions  	//-------------------------------------------------------------------- -public: -	BOOL            isFullyLoaded(); -	BOOL            updateIsFullyLoaded(); -private: -	BOOL            mFullyLoaded; -	BOOL            mPreviousFullyLoaded; -	BOOL            mFullyLoadedInitialized; -	S32             mFullyLoadedFrameCounter; -	LLFrameTimer    mFullyLoadedTimer; -  protected: +	void buildCharacter(); +	void releaseMeshData(); +	void restoreMeshData(); +	void updateMeshData(); +	void computeBodySize(); +	const LLUUID& getStepSound() const; +	BOOL needsRenderBeam(); + +	BOOL			allocateCollisionVolumes( U32 num ); +	void			resetHUDAttachments(); +	static void		getAnimLabels( LLDynamicArray<std::string>* labels ); +	static void		getAnimNames( LLDynamicArray<std::string>* names ); +	//-------------------------------------------------------------------- +	// Textures and Layers +	//-------------------------------------------------------------------- +protected:  	BOOL			loadSkeletonNode();  	BOOL			loadMeshNodes(); -	  	BOOL			isFullyBaked(); -	void			deleteLayerSetCaches(); +	void			deleteLayerSetCaches(bool clearAll = true);  	static BOOL		areAllNearbyInstancesBaked(S32& grey_avatars); -  	static void		onBakedTextureMasksLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); - -	void			setLocalTexture(ELocTexIndex i, LLViewerImage* tex, BOOL baked_version_exits); -	 -	void			requestLayerSetUpdate(LLVOAvatar::ELocTexIndex i); -	void			addLocalTextureStats(LLVOAvatar::ELocTexIndex i, LLViewerImage* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked); +	void			setLocalTexture(LLVOAvatarDefines::ETextureIndex i, LLViewerImage* tex, BOOL baked_version_exits); +	void			requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i); +	void			addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerImage* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked);  	void			addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level);  	static void		onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );  	static void		onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);  	void			useBakedTexture(const LLUUID& id);  	void			dumpAvatarTEs(const std::string& context);  	void			removeMissingBakedTextures(); -	LLTexLayerSet*	getLayerSet(ETextureIndex index) const; +	LLTexLayerSet*	getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;  	LLHost			getObjectHost() const; -	S32				getLocalDiscardLevel( S32 index); +	S32				getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex index); +public: +	static void updateFreezeCounter(S32 counter = 0 ); +private: +	static S32 sFreezeCounter; +	//----------------------------------------------------------------------------------------------- +	// Avatar skeleton setup. +	//----------------------------------------------------------------------------------------------- +private: +	BOOL loadAvatar(); +	BOOL setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); +	BOOL buildSkeleton(const LLVOAvatarSkeletonInfo *info);  	//----------------------------------------------------------------------------------------------- -	// the Voice Visualizer is responsible for detecting the user's voice signal, and when the -	// user speaks, it puts a voice symbol over the avatar's head, and triggering gesticulations +	// Per-avatar information about texture data. +	// To-do: Move this to private implementation class  	//----------------------------------------------------------------------------------------------- -	private: -	LLVoiceVisualizer * mVoiceVisualizer; -	int					mCurrentGesticulationLevel; +private: +	struct BakedTextureData +	{ +		LLUUID			mLastTextureIndex; +		LLTexLayerSet*	mTexLayerSet; +		bool			mIsLoaded; +		LLVOAvatarDefines::ETextureIndex	mTextureIndex; +		U32				mMaskTexName; +		// Stores pointers to the joint meshes that this baked texture deals with +		std::vector< LLViewerJointMesh * > mMeshes;  // std::vector<LLViewerJointMesh> mJoints[i]->mMeshParts +	}; +	typedef std::vector<BakedTextureData> bakedtexturedata_vec_t; +	bakedtexturedata_vec_t mBakedTextureData; + +	struct LocalTextureData +	{ +		LocalTextureData() : mIsBakedReady(FALSE), mDiscard(MAX_DISCARD_LEVEL+1), mImage(NULL) +		{} +		LLPointer<LLViewerImage> mImage; +		BOOL mIsBakedReady; +		S32 mDiscard; +	}; +	typedef std::map<LLVOAvatarDefines::ETextureIndex, LocalTextureData> localtexture_map_t; +	localtexture_map_t mLocalTextureData; + +	typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t; +	polymesh_map_t mMeshes; +	std::vector<LLViewerJoint *> mMeshLOD; +	S32 mNumInitFaces ; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer. +	//----------------------------------------------------------------------------------------------- +	// Static texture/mesh/baked dictionary for avatars +	//----------------------------------------------------------------------------------------------- +public: +	static BOOL isIndexLocalTexture(LLVOAvatarDefines::ETextureIndex i); +	static BOOL isIndexBakedTexture(LLVOAvatarDefines::ETextureIndex i);  private: -	static  S32 sFreezeCounter ; +	static const LLVOAvatarDefines::LLVOAvatarDictionary *getDictionary() { return sAvatarDictionary; } +	static LLVOAvatarDefines::LLVOAvatarDictionary *sAvatarDictionary; +	static LLVOAvatarSkeletonInfo* sAvatarSkeletonInfo; +	static LLVOAvatarXmlInfo* sAvatarXmlInfo; + +	//----------------------------------------------------------------------------------------------- +	// Diagnostics +	//-----------------------------------------------------------------------------------------------  public: -	static void updateFreezeCounter(S32 counter = 0 ) ; +	static F32 		sUnbakedTime; // Total seconds with >=1 unbaked avatars +	static F32 		sUnbakedUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)  +	static F32 		sGreyTime; // Total seconds with >=1 grey avatars +	static F32 		sGreyUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)  + +	const std::string getBakedStatusForPrintout() const;  }; +//----------------------------------------------------------------------------------------------- +// Inlines +//----------------------------------------------------------------------------------------------- +inline BOOL LLVOAvatar::isTextureDefined(U8 te) const +{ +	return (getTEImage(te)->getID() != IMG_DEFAULT_AVATAR && getTEImage(te)->getID() != IMG_DEFAULT); +} + +inline BOOL LLVOAvatar::isTextureVisible(U8 te) const +{ +	return (!isTextureDefined(te) || getTEImage(te)->getID() != IMG_INVISIBLE); +} +  #endif // LL_VO_AVATAR_H diff --git a/indra/newview/llvoavatardefines.cpp b/indra/newview/llvoavatardefines.cpp new file mode 100644 index 0000000000..19ad90a8e2 --- /dev/null +++ b/indra/newview/llvoavatardefines.cpp @@ -0,0 +1,227 @@ +/**  + * @file llvoavatar.cpp + * @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + *  + * Copyright (c) 2001-2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llvoavatardefines.h" + +const S32 LLVOAvatarDefines::SCRATCH_TEX_WIDTH = 512; +const S32 LLVOAvatarDefines::SCRATCH_TEX_HEIGHT = 512; +const S32 LLVOAvatarDefines::IMPOSTOR_PERIOD = 2; + +using namespace LLVOAvatarDefines; + +/********************************************************************************* + * Edit this function to add/remove/change textures and mesh definitions for avatars. + */ +void LLVOAvatarDictionary::initData() +{ +	// Textures +	mTextureMap[TEX_HEAD_BODYPAINT] =            new TextureDictionaryEntry("head bodypaint",   TRUE,  BAKED_NUM_INDICES, "",                          WT_SKIN); +	mTextureMap[TEX_UPPER_SHIRT] =               new TextureDictionaryEntry("shirt",            TRUE,  BAKED_NUM_INDICES, "UIImgDefaultShirtUUID",     WT_SHIRT); +	mTextureMap[TEX_LOWER_PANTS] =               new TextureDictionaryEntry("pants",            TRUE,  BAKED_NUM_INDICES, "UIImgDefaultPantsUUID",     WT_PANTS); +	mTextureMap[TEX_EYES_IRIS] =                 new TextureDictionaryEntry("iris",             TRUE,  BAKED_NUM_INDICES, "UIImgDefaultEyesUUID",      WT_EYES); +	mTextureMap[TEX_HAIR] =                      new TextureDictionaryEntry("hair",             TRUE,  BAKED_NUM_INDICES, "UIImgDefaultHairUUID",      WT_HAIR); +	mTextureMap[TEX_UPPER_BODYPAINT] =           new TextureDictionaryEntry("upper bodypaint",  TRUE,  BAKED_NUM_INDICES, "",                          WT_SKIN); +	mTextureMap[TEX_LOWER_BODYPAINT] =           new TextureDictionaryEntry("lower bodypaint",  TRUE,  BAKED_NUM_INDICES, "",                          WT_SKIN); +	mTextureMap[TEX_LOWER_SHOES] =               new TextureDictionaryEntry("shoes",            TRUE,  BAKED_NUM_INDICES, "UIImgDefaultShoesUUID",     WT_SHOES); +	mTextureMap[TEX_LOWER_SOCKS] =               new TextureDictionaryEntry("socks",            TRUE,  BAKED_NUM_INDICES, "UIImgDefaultSocksUUID",     WT_SOCKS); +	mTextureMap[TEX_UPPER_JACKET] =              new TextureDictionaryEntry("upper jacket",     TRUE,  BAKED_NUM_INDICES, "UIImgDefaultJacketUUID",    WT_JACKET); +	mTextureMap[TEX_LOWER_JACKET] =              new TextureDictionaryEntry("lower jacket",     TRUE,  BAKED_NUM_INDICES, "UIImgDefaultJacketUUID",    WT_JACKET); +	mTextureMap[TEX_UPPER_GLOVES] =              new TextureDictionaryEntry("gloves",           TRUE,  BAKED_NUM_INDICES, "UIImgDefaultGlovesUUID",    WT_GLOVES); +	mTextureMap[TEX_UPPER_UNDERSHIRT] =          new TextureDictionaryEntry("undershirt",       TRUE,  BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERSHIRT); +	mTextureMap[TEX_LOWER_UNDERPANTS] =          new TextureDictionaryEntry("underpants",       TRUE,  BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERPANTS); +	mTextureMap[TEX_SKIRT] =                     new TextureDictionaryEntry("skirt",            TRUE,  BAKED_NUM_INDICES, "UIImgDefaultSkirtUUID",     WT_SKIRT); +	mTextureMap[TEX_HEAD_BAKED] =                new TextureDictionaryEntry("head-baked",       FALSE, BAKED_HEAD); +	mTextureMap[TEX_UPPER_BAKED] =               new TextureDictionaryEntry("upper-baked",      FALSE, BAKED_UPPER); +	mTextureMap[TEX_LOWER_BAKED] =               new TextureDictionaryEntry("lower-baked",      FALSE, BAKED_LOWER); +	mTextureMap[TEX_EYES_BAKED] =                new TextureDictionaryEntry("eyes-baked",       FALSE, BAKED_EYES); +	mTextureMap[TEX_HAIR_BAKED] =                new TextureDictionaryEntry("hair-baked",       FALSE, BAKED_HAIR); +	mTextureMap[TEX_SKIRT_BAKED] =               new TextureDictionaryEntry("skirt-baked",      FALSE, BAKED_SKIRT); + +	// Baked textures +	mBakedTextureMap[BAKED_HEAD] =     new BakedDictionaryEntry(TEX_HEAD_BAKED,  "head",       1, TEX_HEAD_BODYPAINT); +	mBakedTextureMap[BAKED_UPPER] =    new BakedDictionaryEntry(TEX_UPPER_BAKED, "upper_body", 5, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT,TEX_UPPER_JACKET,TEX_UPPER_GLOVES,TEX_UPPER_UNDERSHIRT); +	mBakedTextureMap[BAKED_LOWER] =    new BakedDictionaryEntry(TEX_LOWER_BAKED, "lower_body", 6, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES,TEX_LOWER_SOCKS,TEX_LOWER_JACKET,TEX_LOWER_UNDERPANTS); +	mBakedTextureMap[BAKED_EYES] =     new BakedDictionaryEntry(TEX_EYES_BAKED,  "eyes",       1, TEX_EYES_IRIS); +	mBakedTextureMap[BAKED_SKIRT] =    new BakedDictionaryEntry(TEX_SKIRT_BAKED, "skirt",      1, TEX_SKIRT); +	mBakedTextureMap[BAKED_HAIR] =     new BakedDictionaryEntry(TEX_HAIR_BAKED,  "hair",       1, TEX_HAIR); +		 +	// Meshes +	mMeshMap[MESH_ID_HAIR] =           new MeshDictionaryEntry(BAKED_HAIR,  "hairMesh",         6, LLViewerJoint::PN_4); +	mMeshMap[MESH_ID_HEAD] =           new MeshDictionaryEntry(BAKED_HEAD,  "headMesh",         5, LLViewerJoint::PN_5); +	mMeshMap[MESH_ID_EYELASH] =        new MeshDictionaryEntry(BAKED_HEAD,  "eyelashMesh",      1, LLViewerJoint::PN_0); // no baked mesh associated currently +	mMeshMap[MESH_ID_UPPER_BODY] =     new MeshDictionaryEntry(BAKED_UPPER, "upperBodyMesh",    5, LLViewerJoint::PN_1); +	mMeshMap[MESH_ID_LOWER_BODY] =     new MeshDictionaryEntry(BAKED_LOWER, "lowerBodyMesh",    5, LLViewerJoint::PN_2); +	mMeshMap[MESH_ID_EYEBALL_LEFT] =   new MeshDictionaryEntry(BAKED_EYES,  "eyeBallLeftMesh",  2, LLViewerJoint::PN_3); +	mMeshMap[MESH_ID_EYEBALL_RIGHT] =  new MeshDictionaryEntry(BAKED_EYES,  "eyeBallRightMesh", 2, LLViewerJoint::PN_3); +	mMeshMap[MESH_ID_SKIRT] =          new MeshDictionaryEntry(BAKED_SKIRT, "skirtMesh",        5, LLViewerJoint::PN_5); + +	// Wearables +	mWearableMap[BAKED_HEAD] =   new WearableDictionaryEntry("18ded8d6-bcfc-e415-8539-944c0f5ea7a6", 3, WT_SHAPE, WT_SKIN, WT_HAIR); +	mWearableMap[BAKED_UPPER] =  new WearableDictionaryEntry("338c29e3-3024-4dbb-998d-7c04cf4fa88f", 6, WT_SHAPE, WT_SKIN,	WT_SHIRT, WT_JACKET, WT_GLOVES, WT_UNDERSHIRT); +	mWearableMap[BAKED_LOWER] =  new WearableDictionaryEntry("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f", 7, WT_SHAPE, WT_SKIN,	WT_PANTS, WT_SHOES,	 WT_SOCKS,  WT_JACKET,		WT_UNDERPANTS); +	mWearableMap[BAKED_EYES] =   new WearableDictionaryEntry("b2cf28af-b840-1071-3c6a-78085d8128b5", 1, WT_EYES); +	mWearableMap[BAKED_SKIRT] =  new WearableDictionaryEntry("ea800387-ea1a-14e0-56cb-24f2022f969a", 1, WT_SKIRT); +	mWearableMap[BAKED_HAIR] =   new WearableDictionaryEntry("0af1ef7c-ad24-11dd-8790-001f5bf833e8", 1, WT_HAIR); +} + +/* + * + *********************************************************************************/ + +LLVOAvatarDictionary::LLVOAvatarDictionary() +{ +	initData(); +	createAssociations(); +} + +// Baked textures are composites of textures; for each such composited texture, +// map it to the baked texture. +void LLVOAvatarDictionary::createAssociations() +{ +	for (baked_map_t::const_iterator iter = mBakedTextureMap.begin(); iter != mBakedTextureMap.end(); iter++) +	{ +		const EBakedTextureIndex baked_index = (iter->first); +		const BakedDictionaryEntry *dict = (iter->second); + +		// For each texture that this baked texture index affects, associate those textures +		// with this baked texture index. +		for (texture_vec_t::const_iterator local_texture_iter = dict->mLocalTextures.begin(); +			 local_texture_iter != dict->mLocalTextures.end(); +			 local_texture_iter++) +		{ +			const ETextureIndex local_texture_index = (ETextureIndex) *local_texture_iter; +			mTextureMap[local_texture_index]->mIsUsedByBakedTexture = true; +			mTextureMap[local_texture_index]->mBakedTextureIndex = baked_index; +		} +	} +		 +} + +LLVOAvatarDictionary::TextureDictionaryEntry::TextureDictionaryEntry(const std::string &name,  +																	 bool is_local_texture,  +																	 EBakedTextureIndex baked_texture_index, +																	 const std::string &default_image_name, +																	 EWearableType wearable_type) : +	mName(name), +	mIsLocalTexture(is_local_texture), +	mIsBakedTexture(!is_local_texture), +	mIsUsedByBakedTexture(baked_texture_index != BAKED_NUM_INDICES), +	mBakedTextureIndex(baked_texture_index), +	mDefaultImageName(default_image_name), +	mWearableType(wearable_type) +{ +} + +LLVOAvatarDictionary::MeshDictionaryEntry::MeshDictionaryEntry(EBakedTextureIndex baked_index,  +															   const std::string &name,  +															   U8 level, +															   LLViewerJoint::PickName pick) : +	mBakedID(baked_index), +	mName(name), +	mLOD(level), +	mPickName(pick) +{ +} +LLVOAvatarDictionary::BakedDictionaryEntry::BakedDictionaryEntry(ETextureIndex tex_index,  +																 const std::string &name,  +																 U32 num_local_textures, ... ) : +	mName(name), +	mTextureIndex(tex_index) + +{ +	va_list argp; +	va_start(argp, num_local_textures); +	for (U8 i=0; i < num_local_textures; i++) +	{ +		ETextureIndex t = (ETextureIndex)va_arg(argp,int); +		mLocalTextures.push_back(t); +	} +} + +LLVOAvatarDictionary::WearableDictionaryEntry::WearableDictionaryEntry(const std::string &hash_name,  +																	   U32 num_wearables, ... ) : +	mHashID(LLUUID(hash_name)) +{ +	va_list argp; +	va_start(argp, num_wearables); +	for (U8 i=0; i < num_wearables; i++) +	{ +		EWearableType t = (EWearableType)va_arg(argp,int); +		mWearablesVec.push_back(t); +	} +} + +//virtual  +LLVOAvatarDictionary::~LLVOAvatarDictionary() +{ +	for (mesh_map_t::iterator iter = mMeshMap.begin(); iter != mMeshMap.end(); iter++) +		delete (iter->second); +	for (baked_map_t::iterator iter = mBakedTextureMap.begin(); iter != mBakedTextureMap.end(); iter++) +		delete (iter->second); +	for (texture_map_t::iterator iter = mTextureMap.begin(); iter != mTextureMap.end(); iter++) +		delete (iter->second); +} + +const LLVOAvatarDictionary::MeshDictionaryEntry *LLVOAvatarDictionary::getMesh(EMeshIndex index) const +{ +	mesh_map_t::const_iterator mesh_iter = mMeshMap.find(index); +	if (mesh_iter == mMeshMap.end()) return NULL; +	return mesh_iter->second;  +} + +const LLVOAvatarDictionary::BakedDictionaryEntry *LLVOAvatarDictionary::getBakedTexture(EBakedTextureIndex index) const +{ +	baked_map_t::const_iterator baked_iter = mBakedTextureMap.find(index); +	if (baked_iter == mBakedTextureMap.end()) return NULL; +	return baked_iter->second;  +} + +const LLVOAvatarDictionary::TextureDictionaryEntry *LLVOAvatarDictionary::getTexture(ETextureIndex index) const +{ +	texture_map_t::const_iterator texture_iter = mTextureMap.find(index); +	if (texture_iter == mTextureMap.end()) return NULL; +	return texture_iter->second; +} + +const LLVOAvatarDictionary::WearableDictionaryEntry *LLVOAvatarDictionary::getWearable(EBakedTextureIndex index) const +{ +	wearable_map_t::const_iterator wearable_iter = mWearableMap.find(index); +	if (wearable_iter == mWearableMap.end()) return NULL; +	return wearable_iter->second; +} + + + +ETextureIndex LLVOAvatarDefines::getTextureIndex(EBakedTextureIndex index) +{ +	return LLVOAvatarDictionary::getInstance()->getBakedTexture(index)->mTextureIndex; +} diff --git a/indra/newview/llvoavatardefines.h b/indra/newview/llvoavatardefines.h new file mode 100644 index 0000000000..bc1a1f1c1f --- /dev/null +++ b/indra/newview/llvoavatardefines.h @@ -0,0 +1,209 @@ +/**  + * @file llvoavatar.h + * @brief Declaration of LLVOAvatar class which is a derivation fo + * LLViewerObject + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + *  + * Copyright (c) 2001-2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLVOAVATAR_DEFINES_H +#define LLVOAVATAR_DEFINES_H + +#include <vector> +#include "llwearable.h" +#include "llviewerjoint.h" + +namespace LLVOAvatarDefines +{ + +extern const S32 SCRATCH_TEX_WIDTH; +extern const S32 SCRATCH_TEX_HEIGHT; +extern const S32 IMPOSTOR_PERIOD; + +//-------------------------------------------------------------------- +// texture entry assignment +//-------------------------------------------------------------------- +enum ETextureIndex +{ +	TEX_HEAD_BODYPAINT = 0, +	TEX_UPPER_SHIRT, +	TEX_LOWER_PANTS, +	TEX_EYES_IRIS, +	TEX_HAIR, +	TEX_UPPER_BODYPAINT, +	TEX_LOWER_BODYPAINT, +	TEX_LOWER_SHOES, +	TEX_HEAD_BAKED,			// Pre-composited +	TEX_UPPER_BAKED,		// Pre-composited +	TEX_LOWER_BAKED,		// Pre-composited +	TEX_EYES_BAKED,		// Pre-composited +	TEX_LOWER_SOCKS, +	TEX_UPPER_JACKET, +	TEX_LOWER_JACKET, +	TEX_UPPER_GLOVES, +	TEX_UPPER_UNDERSHIRT, +	TEX_LOWER_UNDERPANTS, +	TEX_SKIRT, +	TEX_SKIRT_BAKED,		// Pre-composited +	TEX_HAIR_BAKED,     // Pre-composited +	TEX_NUM_INDICES +}; // "Note: if TEX_NUM_ENTRIES changes, update AGENT_TEXTURES in llagentinfo.h, mTextureIndexBaked, and BAKED_TEXTURE_COUNT" +// Seraph - Above comment about order is probably obsolete. + +typedef std::vector<ETextureIndex> texture_vec_t; +	 +enum EBakedTextureIndex +{ +	BAKED_HEAD = 0, +	BAKED_UPPER, +	BAKED_LOWER, +	BAKED_EYES, +	BAKED_SKIRT, +	BAKED_HAIR, +	BAKED_NUM_INDICES +}; +typedef std::vector<EBakedTextureIndex> bakedtexture_vec_t; + +// Reference IDs for each mesh. Used as indices for vector of joints +enum EMeshIndex +{ +	MESH_ID_HAIR = 0, +	MESH_ID_HEAD, +	MESH_ID_EYELASH, +	MESH_ID_UPPER_BODY, +	MESH_ID_LOWER_BODY, +	MESH_ID_EYEBALL_LEFT, +	MESH_ID_EYEBALL_RIGHT, +	MESH_ID_SKIRT, +	MESH_ID_NUM_INDICES +}; +typedef std::vector<EMeshIndex> mesh_vec_t; + +typedef std::vector<EWearableType> wearables_vec_t; + +//-------------------------------------------------------------------------------- +// Convenience Functions +//-------------------------------------------------------------------------------- + +// Convert from baked texture to associated texture; e.g. BAKED_HEAD -> TEX_HEAD_BAKED +ETextureIndex getTextureIndex(EBakedTextureIndex t); + + + +//------------------------------------------------------------------------ +// LLVOAvatarDictionary +//  +// Holds dictionary static entries for textures, baked textures, meshes, etc.; i.e. +// information that is common to all avatars. +//  +// This holds const data - it is initialized once and the contents never change after that. +//------------------------------------------------------------------------ +class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary> +{ +public: +	LLVOAvatarDictionary(); +	virtual ~LLVOAvatarDictionary(); +	 +	struct TextureDictionaryEntry +	{ +		TextureDictionaryEntry(const std::string &name,  +							   bool is_local_texture,  +							   EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES, +							   const std::string &default_image_name = "", +							   EWearableType wearable_type = WT_INVALID); +		const std::string mName; +		const std::string mDefaultImageName; +		const EWearableType mWearableType; +		// It's either a local texture xor baked +		BOOL mIsLocalTexture; +		BOOL mIsBakedTexture; +		// If it's a local texture, it may be used by a baked texture +		BOOL mIsUsedByBakedTexture; +		EBakedTextureIndex mBakedTextureIndex; +	}; +	 +	struct MeshDictionaryEntry +	{ +		MeshDictionaryEntry(EBakedTextureIndex baked_index,  +							const std::string &name,  +							U8 level, +							LLViewerJoint::PickName pick); +		const std::string mName; // names of mesh types as they are used in avatar_lad.xml +		// Levels of Detail for each mesh.  Must match levels of detail present in avatar_lad.xml +        // Otherwise meshes will be unable to be found, or levels of detail will be ignored +		const U8 mLOD; +		const EBakedTextureIndex mBakedID; +		const LLViewerJoint::PickName mPickName; +	}; + +	struct BakedDictionaryEntry +	{ +		BakedDictionaryEntry(ETextureIndex tex_index,  +							 const std::string &name,  +							 U32 num_local_textures, ... ); +		const ETextureIndex mTextureIndex; +		const std::string mName; +		texture_vec_t mLocalTextures; +	}; +	 +	struct WearableDictionaryEntry +	{ +		WearableDictionaryEntry(const std::string &hash_name, +								U32 num_wearables, ... ); +		const LLUUID mHashID; +		wearables_vec_t mWearablesVec; +	}; + +	typedef std::map<EBakedTextureIndex, BakedDictionaryEntry*> baked_map_t; +	typedef std::map<ETextureIndex, TextureDictionaryEntry*> texture_map_t; +	typedef std::map<EMeshIndex, MeshDictionaryEntry*> mesh_map_t; +	typedef std::map<EBakedTextureIndex, WearableDictionaryEntry*> wearable_map_t; + +	const MeshDictionaryEntry *getMesh(EMeshIndex index) const; +	const BakedDictionaryEntry *getBakedTexture(EBakedTextureIndex index) const; +	const TextureDictionaryEntry *getTexture(ETextureIndex index) const; +	const WearableDictionaryEntry *getWearable(EBakedTextureIndex index) const; + +	const texture_map_t &getTextures() const { return mTextureMap; } +	const baked_map_t &getBakedTextures() const { return mBakedTextureMap; } +	const mesh_map_t &getMeshes() const { return mMeshMap; } +	const wearable_map_t &getWearables() const { return mWearableMap; } +	 +private: +	void initData(); +	void createAssociations(); + +	texture_map_t mTextureMap; +	baked_map_t mBakedTextureMap; +	mesh_map_t mMeshMap; +	wearable_map_t mWearableMap; + +}; // End LLVOAvatarDictionary + +} // End namespace LLVOAvatarDefines + +#endif diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index d69830b5c3..a5f4dc934a 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -49,6 +49,8 @@  #include "llvoavatar.h"  #include "llwearable.h" +using namespace LLVOAvatarDefines; +  // static  S32 LLWearable::sCurrentDefinitionVersion = 1; @@ -392,6 +394,7 @@ BOOL LLWearable::importFile( LLFILE* file )  	}  	else  	{ +		mType = WT_COUNT;  		llwarns << "Bad Wearable asset: bad type #" << type <<  llendl;  		return FALSE;  	} @@ -501,9 +504,9 @@ BOOL LLWearable::isOldVersion()  	S32 te_count = 0; -	for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) +	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )  	{ -		if( LLVOAvatar::getTEWearableType( te ) == mType ) +		if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )  		{  			te_count++;  			if( !is_in_map(mTEMap, te ) ) @@ -555,9 +558,9 @@ BOOL LLWearable::isDirty()  		}  	} -	for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) +	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )  	{ -		if( LLVOAvatar::getTEWearableType( te ) == mType ) +		if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )  		{  			LLViewerImage* avatar_image = avatar->getTEImage( te );  			if( !avatar_image ) @@ -565,7 +568,7 @@ BOOL LLWearable::isDirty()  				llassert( 0 );  				continue;  			} -			const LLUUID& image_id = get_if_there(mTEMap,  te, LLVOAvatar::getDefaultTEImageID( te ) ); +			const LLUUID& image_id = get_if_there(mTEMap,  te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) );  			if( avatar_image->getID() != image_id )  			{  				return TRUE; @@ -607,11 +610,11 @@ void LLWearable::setParamsToDefaults()  void LLWearable::setTexturesToDefaults()  {  	mTEMap.clear(); -	for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) +	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )  	{ -		if( LLVOAvatar::getTEWearableType( te ) == mType ) +		if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )  		{ -			mTEMap[te] = LLVOAvatar::getDefaultTEImageID( te ); +			mTEMap[te] = LLVOAvatar::getDefaultTEImageID((ETextureIndex) te );  		}  	}  } @@ -654,11 +657,11 @@ void LLWearable::writeToAvatar( BOOL set_by_user )  	}  	// Pull texture entries -	for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) +	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )  	{ -		if( LLVOAvatar::getTEWearableType( te ) == mType ) +		if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )  		{ -			const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID( te ) ); +			const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) );  			LLViewerImage* image = gImageList.getImage( image_id );  			avatar->setLocTexTE( te, image, set_by_user );  		} @@ -731,9 +734,9 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user )  	// Pull textures  	LLViewerImage* image = gImageList.getImage( IMG_DEFAULT_AVATAR ); -	for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) +	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )  	{ -		if( LLVOAvatar::getTEWearableType( te ) == type ) +		if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == type )  		{  			avatar->setLocTexTE( te, image, set_by_user );  		} @@ -777,9 +780,9 @@ void LLWearable::readFromAvatar()  	}  	mTEMap.clear(); -	for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) +	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )  	{ -		if( LLVOAvatar::getTEWearableType( te ) == mType ) +		if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )  		{  			LLViewerImage* image = avatar->getTEImage( te );  			if( image ) @@ -828,11 +831,11 @@ void LLWearable::copyDataFrom( LLWearable* src )  	}  	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed) -	for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) +	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )  	{ -		if( LLVOAvatar::getTEWearableType( te ) == mType ) +		if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )  		{ -			const LLUUID& image_id = get_if_there(src->mTEMap, te, LLVOAvatar::getDefaultTEImageID( te ) ); +			const LLUUID& image_id = get_if_there(src->mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) );  			mTEMap[te] = image_id;  		}  	} diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index dc1a6744e0..683a8fa928 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -66,8 +66,8 @@ class LLWearable  public:  	~LLWearable(); -	const LLAssetID&		getID() { return mAssetID; } -	const LLTransactionID&		getTransactionID() { return mTransactionID; } +	const LLAssetID&		getID() const { return mAssetID; } +	const LLTransactionID&		getTransactionID() const { return mTransactionID; }  	BOOL				isDirty();  	BOOL				isOldVersion(); @@ -84,16 +84,16 @@ public:  	void				setType( EWearableType type )			{ mType = type; }  	void				setName( const std::string& name )			{ mName = name; } -	const std::string&	getName()								{ return mName; } +	const std::string&	getName() const								{ return mName; }  	void				setDescription( const std::string& desc )	{ mDescription = desc; } -	const std::string&	getDescription()						{ return mDescription; } +	const std::string&	getDescription() const						{ return mDescription; }  	void				setPermissions( const LLPermissions& p ) { mPermissions = p; } -	const LLPermissions& getPermissions()						{ return mPermissions; } +	const LLPermissions& getPermissions() const						{ return mPermissions; }  	void				setSaleInfo( const LLSaleInfo& info )	{ mSaleInfo = info; } -	const LLSaleInfo&	getSaleInfo()							{ return mSaleInfo; } +	const LLSaleInfo&	getSaleInfo() const							{ return mSaleInfo; }  	const std::string&	getTypeLabel() const					{ return LLWearable::sTypeLabel[ mType ]; }  	const std::string&	getTypeName() const						{ return LLWearable::sTypeName[ mType ]; } diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 083d7e1581..512c03fa4d 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -102,6 +102,7 @@ void LLWearableList::getAsset( const LLAssetID& assetID, const std::string& wear  // static  void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID& uuid, void* userdata, S32 status, LLExtStat ext_status )  { +	BOOL isNewWearable = FALSE;  	LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;  	LLWearable* wearable = NULL; // NULL indicates failure @@ -124,6 +125,10 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID  			bool res = wearable->importFile( fp );  			if (!res)  			{ +				if (wearable->getType() == WT_COUNT) +				{ +					isNewWearable = TRUE; +				}  				delete wearable;  				wearable = NULL;  			} @@ -184,7 +189,11 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID  		LLSD args;  		// *TODO:translate  		args["TYPE"] = LLAssetType::lookupHumanReadable(data->mAssetType); -		if (data->mName.empty()) +		if (isNewWearable) +		{ +			LLNotifications::instance().add("InvalidWearable"); +		} +		else if (data->mName.empty())  		{  			LLNotifications::instance().add("FailedToFindWearableUnnamed", args);  		} diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3a5e41e3ca..d90eaa9d9b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -232,6 +232,7 @@ BOOL	LLPipeline::sRenderParticleBeacons = FALSE;  BOOL	LLPipeline::sRenderSoundBeacons = FALSE;  BOOL	LLPipeline::sRenderBeacons = FALSE;  BOOL	LLPipeline::sRenderHighlight = TRUE; +BOOL	LLPipeline::sForceOldBakedUpload = FALSE;  S32		LLPipeline::sUseOcclusion = 0;  BOOL	LLPipeline::sDelayVBUpdate = TRUE;  BOOL	LLPipeline::sFastAlpha = TRUE; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e8673c7d4c..ca0f4af1ac 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -391,6 +391,7 @@ public:  	static S32				sCompiles;  	static BOOL				sShowHUDAttachments; +	static BOOL				sForceOldBakedUpload; // If true will not use capabilities to upload baked textures.  	static S32				sUseOcclusion;  // 0 = no occlusion, 1 = read only, 2 = read/write  	static BOOL				sDelayVBUpdate;  	static BOOL				sFastAlpha; | 
