PageRenderTime 166ms CodeModel.GetById 45ms app.highlight 111ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llwearable.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1271 lines | 981 code | 138 blank | 152 comment | 227 complexity | 9daeeaf7ffee67adcb72c1c25507eb4d MD5 | raw file
   1/** 
   2 * @file llwearable.cpp
   3 * @brief LLWearable class implementation
   4 *
   5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "llviewerprecompiledheaders.h"
  28
  29#include "llagent.h"
  30#include "llagentcamera.h"
  31#include "llagentwearables.h"
  32#include "lldictionary.h"
  33#include "llfloatersidepanelcontainer.h"
  34#include "lllocaltextureobject.h"
  35#include "llnotificationsutil.h"
  36#include "llviewertexturelist.h"
  37#include "llinventorymodel.h"
  38#include "llinventoryobserver.h"
  39#include "llsidepanelappearance.h"
  40#include "lltexlayer.h"
  41#include "lltexglobalcolor.h"
  42#include "lltrans.h"
  43#include "llviewerregion.h"
  44#include "llvisualparam.h"
  45#include "llvoavatar.h"
  46#include "llvoavatarself.h"
  47#include "llvoavatardefines.h"
  48#include "llwearable.h"
  49#include "llviewercontrol.h"
  50
  51using namespace LLVOAvatarDefines;
  52
  53// static
  54S32 LLWearable::sCurrentDefinitionVersion = 1;
  55
  56// support class - remove for 2.1 (hackity hack hack)
  57class LLOverrideBakedTextureUpdate
  58{
  59public:
  60	LLOverrideBakedTextureUpdate(bool temp_state)
  61	{
  62		U32 num_bakes = (U32) LLVOAvatarDefines::BAKED_NUM_INDICES;
  63		for( U32 index = 0; index < num_bakes; ++index )
  64		{
  65			composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index);
  66		}
  67		gAgentAvatarp->setCompositeUpdatesEnabled(temp_state);
  68	}
  69
  70	~LLOverrideBakedTextureUpdate()
  71	{
  72		U32 num_bakes = (U32)LLVOAvatarDefines::BAKED_NUM_INDICES;		
  73		for( U32 index = 0; index < num_bakes; ++index )
  74		{
  75			gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]);
  76		}
  77	}
  78private:
  79	bool composite_enabled[LLVOAvatarDefines::BAKED_NUM_INDICES];
  80};
  81
  82// Private local functions
  83static std::string terse_F32_to_string(F32 f);
  84static std::string asset_id_to_filename(const LLUUID &asset_id);
  85
  86LLWearable::LLWearable(const LLTransactionID& transaction_id) :
  87	mDefinitionVersion(LLWearable::sCurrentDefinitionVersion),
  88	mType(LLWearableType::WT_INVALID)
  89{
  90	mTransactionID = transaction_id;
  91	mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
  92}
  93
  94LLWearable::LLWearable(const LLAssetID& asset_id) :
  95	mDefinitionVersion( LLWearable::sCurrentDefinitionVersion ),
  96	mType(LLWearableType::WT_INVALID)
  97{
  98	mAssetID = asset_id;
  99	mTransactionID.setNull();
 100}
 101
 102LLWearable::~LLWearable()
 103{
 104}
 105
 106const std::string& LLWearable::getTypeLabel() const
 107{
 108	return LLWearableType::getTypeLabel(mType);
 109}
 110
 111const std::string& LLWearable::getTypeName() const
 112{
 113	return LLWearableType::getTypeName(mType);
 114}
 115
 116LLAssetType::EType LLWearable::getAssetType() const
 117{
 118	return LLWearableType::getAssetType(mType);
 119}
 120
 121BOOL LLWearable::exportFile(LLFILE* file) const
 122{
 123	// header and version
 124	if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
 125	{
 126		return FALSE;
 127	}
 128
 129	// name
 130	if( fprintf( file, "%s\n", mName.c_str() ) < 0 )
 131	{
 132		return FALSE;
 133	}
 134
 135	// description
 136	if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 )
 137	{
 138		return FALSE;
 139	}
 140	
 141	// permissions
 142	if( !mPermissions.exportFile( file ) )
 143	{
 144		return FALSE;
 145	}
 146
 147	// sale info
 148	if( !mSaleInfo.exportFile( file ) )
 149	{
 150		return FALSE;
 151	}
 152
 153	// wearable type
 154	S32 type = (S32)mType;
 155	if( fprintf( file, "type %d\n", type ) < 0 )
 156	{
 157		return FALSE;
 158	}
 159
 160	// parameters
 161	S32 num_parameters = mVisualParamIndexMap.size();
 162	if( fprintf( file, "parameters %d\n", num_parameters ) < 0 )
 163	{
 164		return FALSE;
 165	}
 166
 167	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
 168		 iter != mVisualParamIndexMap.end(); 
 169		 ++iter)
 170	{
 171		S32 param_id = iter->first;
 172		const LLVisualParam* param = iter->second;
 173		F32 param_weight = param->getWeight();
 174		if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 )
 175		{
 176			return FALSE;
 177		}
 178	}
 179
 180	// texture entries
 181	S32 num_textures = mTEMap.size();
 182	if( fprintf( file, "textures %d\n", num_textures ) < 0 )
 183	{
 184		return FALSE;
 185	}
 186	
 187	for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
 188	{
 189		S32 te = iter->first;
 190		const LLUUID& image_id = iter->second->getID();
 191		if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 )
 192		{
 193			return FALSE;
 194		}
 195	}
 196	return TRUE;
 197}
 198
 199
 200void LLWearable::createVisualParams()
 201{
 202	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
 203		 param;
 204		 param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam())
 205	{
 206		if (param->getWearableType() == mType)
 207		{
 208			addVisualParam(param->cloneParam(this));
 209		}
 210	}
 211
 212	// resync driver parameters to point to the newly cloned driven parameters
 213	for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin(); 
 214		 param_iter != mVisualParamIndexMap.end(); 
 215		 ++param_iter)
 216	{
 217		LLVisualParam* param = param_iter->second;
 218		LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam; 
 219		// need this line to disambiguate between versions of LLCharacter::getVisualParam()
 220		LLVisualParam*(LLVOAvatarSelf::*avatar_function)(S32)const = &LLVOAvatarSelf::getVisualParam; 
 221		param->resetDrivenParams();
 222		if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false))
 223		{
 224			if( !param->linkDrivenParams(boost::bind(avatar_function,gAgentAvatarp,_1 ), true))
 225			{
 226				llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
 227				continue;
 228			}
 229		}
 230	}
 231}
 232
 233BOOL LLWearable::importFile( LLFILE* file )
 234{
 235	// *NOTE: changing the type or size of this buffer will require
 236	// changes in the fscanf() code below. You would be better off
 237	// rewriting this to use streams and not require an open FILE.
 238	char text_buffer[2048];		/* Flawfinder: ignore */
 239	S32 fields_read = 0;
 240
 241	// suppress texlayerset updates while wearables are being imported. Layersets will be updated
 242	// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
 243	LLOverrideBakedTextureUpdate stop_bakes(false);
 244
 245	// read header and version 
 246	fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion );
 247	if( fields_read != 1 )
 248	{
 249		// Shouldn't really log the asset id for security reasons, but
 250		// we need it in this case.
 251		llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
 252		//gVFS->dumpMap();
 253		return FALSE;
 254	}
 255
 256
 257	// Temoprary hack to allow wearables with definition version 24 to still load.
 258	// This should only affect lindens and NDA'd testers who have saved wearables in 2.0
 259	// the extra check for version == 24 can be removed before release, once internal testers
 260	// have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
 261	// these wearables get re-saved with version definition 22.
 262	if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
 263	{
 264		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
 265		return FALSE;
 266	}
 267
 268	// name
 269	int next_char = fgetc( file );		/* Flawfinder: ignore */
 270	if( '\n' == next_char )
 271	{
 272		// no name
 273		mName = "";
 274	}
 275	else
 276	{
 277		ungetc( next_char, file );
 278		fields_read = fscanf(	/* Flawfinder: ignore */
 279			file,
 280			"%2047[^\n]",
 281			text_buffer);
 282		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */
 283		{
 284			llwarns << "Bad Wearable asset: early end of file" << llendl;
 285			return FALSE;
 286		}
 287		mName = text_buffer;
 288		LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
 289	}
 290
 291	// description
 292	next_char = fgetc( file );		/* Flawfinder: ignore */
 293	if( '\n' == next_char )
 294	{
 295		// no description
 296		mDescription = "";
 297	}
 298	else
 299	{
 300		ungetc( next_char, file );
 301		fields_read = fscanf(	/* Flawfinder: ignore */
 302			file,
 303			"%2047[^\n]",
 304			text_buffer );
 305		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */
 306		{
 307			llwarns << "Bad Wearable asset: early end of file" << llendl;
 308			return FALSE;
 309		}
 310		mDescription = text_buffer;
 311		LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
 312	}
 313
 314	// permissions
 315	S32 perm_version;
 316	fields_read = fscanf( file, " permissions %d\n", &perm_version );
 317	if( (fields_read != 1) || (perm_version != 0) )
 318	{
 319		llwarns << "Bad Wearable asset: missing permissions" << llendl;
 320		return FALSE;
 321	}
 322	if( !mPermissions.importFile( file ) )
 323	{
 324		return FALSE;
 325	}
 326
 327	// sale info
 328	S32 sale_info_version;
 329	fields_read = fscanf( file, " sale_info %d\n", &sale_info_version );
 330	if( (fields_read != 1) || (sale_info_version != 0) )
 331	{
 332		llwarns << "Bad Wearable asset: missing sale_info" << llendl;
 333		return FALSE;
 334	}
 335	// Sale info used to contain next owner perm. It is now in the
 336	// permissions. Thus, we read that out, and fix legacy
 337	// objects. It's possible this op would fail, but it should pick
 338	// up the vast majority of the tasks.
 339	BOOL has_perm_mask = FALSE;
 340	U32 perm_mask = 0;
 341	if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) )
 342	{
 343		return FALSE;
 344	}
 345	if(has_perm_mask)
 346	{
 347		// fair use fix.
 348		if(!(perm_mask & PERM_COPY))
 349		{
 350			perm_mask |= PERM_TRANSFER;
 351		}
 352		mPermissions.setMaskNext(perm_mask);
 353	}
 354
 355	// wearable type
 356	S32 type = -1;
 357	fields_read = fscanf( file, "type %d\n", &type );
 358	if( fields_read != 1 )
 359	{
 360		llwarns << "Bad Wearable asset: bad type" << llendl;
 361		return FALSE;
 362	}
 363	if( 0 <= type && type < LLWearableType::WT_COUNT )
 364	{
 365		setType((LLWearableType::EType)type);
 366	}
 367	else
 368	{
 369		mType = LLWearableType::WT_COUNT;
 370		llwarns << "Bad Wearable asset: bad type #" << type <<  llendl;
 371		return FALSE;
 372	}
 373
 374	// parameters header
 375	S32 num_parameters = 0;
 376	fields_read = fscanf( file, "parameters %d\n", &num_parameters );
 377	if( fields_read != 1 )
 378	{
 379		llwarns << "Bad Wearable asset: missing parameters block" << llendl;
 380		return FALSE;
 381	}
 382
 383	if( num_parameters != mVisualParamIndexMap.size() )
 384	{
 385		llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. type: " <<  mType << llendl;
 386	}
 387
 388	// parameters
 389	S32 i;
 390	for( i = 0; i < num_parameters; i++ )
 391	{
 392		S32 param_id = 0;
 393		F32 param_weight = 0.f;
 394		fields_read = fscanf( file, "%d %f\n", &param_id, &param_weight );
 395		if( fields_read != 2 )
 396		{
 397			llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
 398			return FALSE;
 399		}
 400		mSavedVisualParamMap[param_id] = param_weight;
 401	}
 402
 403	// textures header
 404	S32 num_textures = 0;
 405	fields_read = fscanf( file, "textures %d\n", &num_textures);
 406	if( fields_read != 1 )
 407	{
 408		llwarns << "Bad Wearable asset: missing textures block" << llendl;
 409		return FALSE;
 410	}
 411
 412	// textures
 413	for( i = 0; i < num_textures; i++ )
 414	{
 415		S32 te = 0;
 416		fields_read = fscanf(	/* Flawfinder: ignore */
 417			file,
 418			"%d %2047s\n",
 419			&te, text_buffer);
 420		if( fields_read != 2 )
 421		{
 422			llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
 423			return FALSE;
 424		}
 425
 426		if( !LLUUID::validate( text_buffer ) )
 427		{
 428			llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
 429			return FALSE;
 430		}
 431		LLUUID id = LLUUID(text_buffer);
 432		LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( id );
 433		if( mTEMap.find(te) != mTEMap.end() )
 434		{
 435			delete mTEMap[te];
 436		}
 437		if( mSavedTEMap.find(te) != mSavedTEMap.end() )
 438		{
 439			delete mSavedTEMap[te];
 440		}
 441
 442		if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
 443		{
 444			image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL);
 445		}
 446		LLUUID textureid(text_buffer);
 447		mTEMap[te] = new LLLocalTextureObject(image, textureid);
 448		mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
 449		createLayers(te);
 450	}
 451
 452	// copy all saved param values to working params
 453	revertValues();
 454
 455	return TRUE;
 456}
 457
 458
 459// Avatar parameter and texture definitions can change over time.
 460// This function returns true if parameters or textures have been added or removed
 461// since this wearable was created.
 462BOOL LLWearable::isOldVersion() const
 463{
 464	if (!isAgentAvatarValid()) return FALSE;
 465
 466	if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
 467	{
 468		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
 469		llassert(0);
 470	}
 471
 472	if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
 473	{
 474		return TRUE;
 475	}
 476
 477	S32 param_count = 0;
 478	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
 479		param;
 480		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
 481	{
 482		if( (param->getWearableType() == mType) && (param->isTweakable() ) )
 483		{
 484			param_count++;
 485			if( !is_in_map(mVisualParamIndexMap, param->getID() ) )
 486			{
 487				return TRUE;
 488			}
 489		}
 490	}
 491	if( param_count != mVisualParamIndexMap.size() )
 492	{
 493		return TRUE;
 494	}
 495
 496
 497	S32 te_count = 0;
 498	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
 499	{
 500		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
 501		{
 502			te_count++;
 503			if( !is_in_map(mTEMap, te ) )
 504			{
 505				return TRUE;
 506			}
 507		}
 508	}
 509	if( te_count != mTEMap.size() )
 510	{
 511		return TRUE;
 512	}
 513
 514	return FALSE;
 515}
 516
 517// Avatar parameter and texture definitions can change over time.
 518// * If parameters or textures have been REMOVED since the wearable was created,
 519// they're just ignored, so we consider the wearable clean even though isOldVersion()
 520// will return true. 
 521// * If parameters or textures have been ADDED since the wearable was created,
 522// they are taken to have default values, so we consider the wearable clean
 523// only if those values are the same as the defaults.
 524BOOL LLWearable::isDirty() const
 525{
 526	if (!isAgentAvatarValid()) return FALSE;
 527
 528	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
 529		param;
 530		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
 531	{
 532		if( (param->getWearableType() == mType) 
 533			&& (param->isTweakable() ) 
 534			&& !param->getCrossWearable())
 535		{
 536			F32 current_weight = getVisualParamWeight(param->getID());
 537			current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() );
 538			F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight());
 539			saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() );
 540			
 541			U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() );
 542			U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() );
 543			if( a != b  )
 544			{
 545				return TRUE;
 546			}
 547		}
 548	}
 549
 550	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
 551	{
 552		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
 553		{
 554			te_map_t::const_iterator current_iter = mTEMap.find(te);
 555			if(current_iter != mTEMap.end())
 556			{
 557 				const LLUUID& current_image_id = current_iter->second->getID();
 558				te_map_t::const_iterator saved_iter = mSavedTEMap.find(te);
 559				if(saved_iter != mSavedTEMap.end())
 560				{
 561					const LLUUID& saved_image_id = saved_iter->second->getID();
 562					if (saved_image_id != current_image_id)
 563					{
 564						// saved vs current images are different, wearable is dirty
 565						return TRUE;
 566					}
 567				}
 568				else
 569				{
 570					// image found in current image list but not saved image list
 571					return TRUE;
 572				}
 573			}
 574		}
 575	}
 576
 577	return FALSE;
 578}
 579
 580
 581void LLWearable::setParamsToDefaults()
 582{
 583	if (!isAgentAvatarValid()) return;
 584
 585	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
 586	{
 587		if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable() ) )
 588		{
 589			setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE);
 590		}
 591	}
 592}
 593
 594void LLWearable::setTexturesToDefaults()
 595{
 596	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
 597	{
 598		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
 599		{
 600			LLUUID id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
 601			LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id );
 602			if( mTEMap.find(te) == mTEMap.end() )
 603			{
 604				mTEMap[te] = new LLLocalTextureObject(image, id);
 605				createLayers(te);
 606			}
 607			else
 608			{
 609				// Local Texture Object already created, just set image and UUID
 610				LLLocalTextureObject *lto = mTEMap[te];
 611				lto->setID(id);
 612				lto->setImage(image);
 613			}
 614		}
 615	}
 616}
 617
 618// Updates the user's avatar's appearance
 619void LLWearable::writeToAvatar()
 620{
 621	if (!isAgentAvatarValid()) return;
 622
 623	ESex old_sex = gAgentAvatarp->getSex();
 624
 625	// Pull params
 626	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
 627	{
 628		// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
 629		// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
 630		if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) )
 631		{
 632			S32 param_id = param->getID();
 633			F32 weight = getVisualParamWeight(param_id);
 634
 635			gAgentAvatarp->setVisualParamWeight( param_id, weight, FALSE );
 636		}
 637	}
 638
 639	// Pull texture entries
 640	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
 641	{
 642		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
 643		{
 644			te_map_t::const_iterator iter = mTEMap.find(te);
 645			LLUUID image_id;
 646			if(iter != mTEMap.end())
 647			{
 648				image_id = iter->second->getID();
 649			}
 650			else
 651			{	
 652				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
 653			}
 654			LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );
 655			// MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this.
 656			gAgentAvatarp->setLocalTextureTE(te, image, 0);
 657		}
 658	}
 659
 660	ESex new_sex = gAgentAvatarp->getSex();
 661	if( old_sex != new_sex )
 662	{
 663		gAgentAvatarp->updateSexDependentLayerSets( FALSE );
 664	}	
 665	
 666//	if( upload_bake )
 667//	{
 668//		gAgent.sendAgentSetAppearance();
 669//	}
 670}
 671
 672
 673// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values.
 674// static 
 675void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake )
 676{
 677	if (!isAgentAvatarValid()) return;
 678
 679	// You can't just remove body parts.
 680	if( (type == LLWearableType::WT_SHAPE) ||
 681		(type == LLWearableType::WT_SKIN) ||
 682		(type == LLWearableType::WT_HAIR) ||
 683		(type == LLWearableType::WT_EYES) )
 684	{
 685		return;
 686	}
 687
 688	// Pull params
 689	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
 690	{
 691		if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable() ) )
 692		{
 693			S32 param_id = param->getID();
 694			gAgentAvatarp->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake );
 695		}
 696	}
 697
 698	if(gAgentCamera.cameraCustomizeAvatar())
 699	{
 700		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
 701	}
 702
 703	gAgentAvatarp->updateVisualParams();
 704	gAgentAvatarp->wearableUpdated(type, FALSE);
 705
 706//	if( upload_bake )
 707//	{
 708//		gAgent.sendAgentSetAppearance();
 709//	}
 710}
 711
 712// Does not copy mAssetID.
 713// Definition version is current: removes obsolete enties and creates default values for new ones.
 714void LLWearable::copyDataFrom(const LLWearable* src)
 715{
 716	if (!isAgentAvatarValid()) return;
 717
 718	mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
 719
 720	mName = src->mName;
 721	mDescription = src->mDescription;
 722	mPermissions = src->mPermissions;
 723	mSaleInfo = src->mSaleInfo;
 724
 725	setType(src->mType);
 726
 727	mSavedVisualParamMap.clear();
 728	// Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed)
 729	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
 730		param;
 731		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
 732	{
 733		if( (param->getWearableType() == mType) )
 734		{
 735			S32 id = param->getID();
 736			F32 weight = src->getVisualParamWeight(id);
 737			mSavedVisualParamMap[id] = weight;
 738		}
 739	}
 740
 741	destroyTextures();
 742	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
 743	for (S32 te = 0; te < TEX_NUM_INDICES; te++)
 744	{
 745		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
 746		{
 747			te_map_t::const_iterator iter = src->mTEMap.find(te);
 748			LLUUID image_id;
 749			LLViewerFetchedTexture *image = NULL;
 750			if(iter != src->mTEMap.end())
 751			{
 752				image = src->getLocalTextureObject(te)->getImage();
 753				image_id = src->getLocalTextureObject(te)->getID();
 754				mTEMap[te] = new LLLocalTextureObject(image, image_id);
 755				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
 756				mTEMap[te]->setBakedReady(src->getLocalTextureObject(te)->getBakedReady());
 757				mTEMap[te]->setDiscard(src->getLocalTextureObject(te)->getDiscard());
 758			}
 759			else
 760			{
 761				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
 762				image = LLViewerTextureManager::getFetchedTexture( image_id );
 763				mTEMap[te] = new LLLocalTextureObject(image, image_id);
 764				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
 765			}
 766			createLayers(te);
 767		}
 768	}
 769
 770	// Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable
 771	// to be the same as the saved values (which were loaded from src at param->cloneParam(this))
 772	revertValues();
 773}
 774
 775void LLWearable::setItemID(const LLUUID& item_id)
 776{
 777	mItemID = item_id;
 778}
 779
 780const LLUUID& LLWearable::getItemID() const
 781{
 782	return mItemID;
 783}
 784
 785void LLWearable::setType(LLWearableType::EType type) 
 786{ 
 787	mType = type; 
 788	createVisualParams();
 789}
 790
 791LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
 792{
 793	te_map_t::iterator iter = mTEMap.find(index);
 794	if( iter != mTEMap.end() )
 795	{
 796		LLLocalTextureObject* lto = iter->second;
 797		return lto;
 798	}
 799	return NULL;
 800}
 801
 802const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
 803{
 804	te_map_t::const_iterator iter = mTEMap.find(index);
 805	if( iter != mTEMap.end() )
 806	{
 807		const LLLocalTextureObject* lto = iter->second;
 808		return lto;
 809	}
 810	return NULL;
 811}
 812
 813void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
 814{
 815	if( mTEMap.find(index) != mTEMap.end() )
 816	{
 817		mTEMap.erase(index);
 818	}
 819	mTEMap[index] = new LLLocalTextureObject(lto);
 820}
 821
 822
 823void LLWearable::addVisualParam(LLVisualParam *param)
 824{
 825	if( mVisualParamIndexMap[param->getID()] )
 826	{
 827		delete mVisualParamIndexMap[param->getID()];
 828	}
 829	param->setIsDummy(FALSE);
 830	mVisualParamIndexMap[param->getID()] = param;
 831	mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
 832}
 833
 834void LLWearable::setVisualParams()
 835{
 836	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
 837	{
 838		S32 id = iter->first;
 839		LLVisualParam *wearable_param = iter->second;
 840		F32 value = wearable_param->getWeight();
 841		gAgentAvatarp->setVisualParamWeight(id, value, FALSE);
 842	}
 843}
 844
 845
 846void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
 847{
 848	if( is_in_map(mVisualParamIndexMap, param_index ) )
 849	{
 850		LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
 851		wearable_param->setWeight(value, upload_bake);
 852	}
 853	else
 854	{
 855		llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
 856	}
 857}
 858
 859F32 LLWearable::getVisualParamWeight(S32 param_index) const
 860{
 861	if( is_in_map(mVisualParamIndexMap, param_index ) )
 862	{
 863		const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
 864		return wearable_param->getWeight();
 865	}
 866	else
 867	{
 868		llwarns << "LLWerable::getVisualParam passed invalid parameter index: "  << param_index << " for wearable type: " << this->getName() << llendl;
 869	}
 870	return (F32)-1.0;
 871}
 872
 873LLVisualParam* LLWearable::getVisualParam(S32 index) const
 874{
 875	visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
 876	return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
 877}
 878
 879
 880void LLWearable::getVisualParams(visual_param_vec_t &list)
 881{
 882	visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
 883	visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
 884
 885	// add all visual params to the passed-in vector
 886	for( ; iter != end; ++iter )
 887	{
 888		list.push_back(iter->second);
 889	}
 890}
 891
 892void LLWearable::animateParams(F32 delta, BOOL upload_bake)
 893{
 894	for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
 895		 iter != mVisualParamIndexMap.end();
 896		 ++iter)
 897	{
 898		LLVisualParam *param = (LLVisualParam*) iter->second;
 899		param->animate(delta, upload_bake);
 900	}
 901}
 902
 903LLColor4 LLWearable::getClothesColor(S32 te) const
 904{
 905	LLColor4 color;
 906	U32 param_name[3];
 907	if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) )
 908	{
 909		for( U8 index = 0; index < 3; index++ )
 910		{
 911			color.mV[index] = getVisualParamWeight(param_name[index]);
 912		}
 913	}
 914	return color;
 915}
 916
 917void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
 918{
 919	U32 param_name[3];
 920	if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) )
 921	{
 922		for( U8 index = 0; index < 3; index++ )
 923		{
 924			setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
 925		}
 926	}
 927}
 928
 929void LLWearable::revertValues()
 930{
 931	//update saved settings so wearable is no longer dirty
 932	// non-driver params first
 933	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
 934	{
 935		S32 id = iter->first;
 936		F32 value = iter->second;
 937		LLVisualParam *param = getVisualParam(id);
 938		if(param &&  !dynamic_cast<LLDriverParam*>(param) )
 939		{
 940			setVisualParamWeight(id, value, TRUE);
 941		}
 942	}
 943
 944	//then driver params
 945	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
 946	{
 947		S32 id = iter->first;
 948		F32 value = iter->second;
 949		LLVisualParam *param = getVisualParam(id);
 950		if(param &&  dynamic_cast<LLDriverParam*>(param) )
 951		{
 952			setVisualParamWeight(id, value, TRUE);
 953		}
 954	}
 955
 956	// make sure that saved values are sane
 957	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
 958	{
 959		S32 id = iter->first;
 960		LLVisualParam *param = getVisualParam(id);
 961		if( param )
 962		{
 963			mSavedVisualParamMap[id] = param->getWeight();
 964		}
 965	}
 966
 967	syncImages(mSavedTEMap, mTEMap);
 968
 969
 970	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
 971	if( panel )
 972	{
 973		panel->updateScrollingPanelList();
 974	}
 975}
 976
 977BOOL LLWearable::isOnTop() const
 978{ 
 979	return (this == gAgentWearables.getTopWearable(mType));
 980}
 981
 982void LLWearable::createLayers(S32 te)
 983{
 984	LLTexLayerSet *layer_set = gAgentAvatarp->getLayerSet((ETextureIndex)te);
 985	if (layer_set)
 986	{
 987		layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
 988	}
 989	else
 990	{
 991		llerrs << "could not find layerset for LTO in wearable!" << llendl;
 992	}
 993}
 994
 995void LLWearable::saveValues()
 996{
 997	//update saved settings so wearable is no longer dirty
 998	mSavedVisualParamMap.clear();
 999	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
1000	{
1001		S32 id = iter->first;
1002		LLVisualParam *wearable_param = iter->second;
1003		F32 value = wearable_param->getWeight();
1004		mSavedVisualParamMap[id] = value;
1005	}
1006
1007	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
1008	syncImages(mTEMap, mSavedTEMap);
1009
1010
1011	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
1012	if( panel )
1013	{
1014		panel->updateScrollingPanelList();
1015	}
1016}
1017
1018void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
1019{
1020	// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
1021	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
1022	{
1023		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
1024		{
1025			te_map_t::const_iterator iter = src.find(te);
1026			LLUUID image_id;
1027			LLViewerFetchedTexture *image = NULL;
1028			LLLocalTextureObject *lto = NULL;
1029			if(iter != src.end())
1030			{
1031				// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
1032				lto = iter->second;
1033				image = lto->getImage();
1034				image_id = lto->getID();
1035			}
1036			else
1037			{
1038				// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
1039				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
1040				image = LLViewerTextureManager::getFetchedTexture( image_id );
1041			}
1042
1043			if( dst.find(te) != dst.end() )
1044			{
1045				// there's already an entry in the destination map for the texture. Just update its values.
1046				dst[te]->setImage(image);
1047				dst[te]->setID(image_id);
1048			}
1049			else
1050			{
1051				// no entry found in the destination map, we need to create a new Local Texture Object
1052				dst[te] = new LLLocalTextureObject(image, image_id);
1053			}
1054
1055			if( lto )
1056			{
1057				// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
1058				dst[te]->setBakedReady(lto->getBakedReady());
1059				dst[te]->setDiscard(lto->getDiscard());
1060			}
1061		}
1062	}
1063}
1064
1065void LLWearable::destroyTextures()
1066{
1067	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
1068	{
1069		LLLocalTextureObject *lto = iter->second;
1070		delete lto;
1071	}
1072	mTEMap.clear();
1073	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
1074	{
1075		LLLocalTextureObject *lto = iter->second;
1076		delete lto;
1077	}
1078	mSavedTEMap.clear();
1079}
1080
1081void LLWearable::pullCrossWearableValues()
1082{
1083	// scan through all of the avatar's visual parameters
1084	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
1085		 param;
1086		 param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam())
1087	{
1088		if( param )
1089		{
1090			LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param);
1091			if(driver_param)
1092			{
1093				// parameter is a driver parameter, have it update its 
1094				driver_param->updateCrossDrivenParams(getType());
1095			}
1096		}
1097	}
1098}
1099
1100
1101void LLWearable::setLabelUpdated() const
1102{ 
1103	gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());
1104}
1105
1106void LLWearable::refreshName()
1107{
1108	LLUUID item_id = getItemID();
1109	LLInventoryItem* item = gInventory.getItem(item_id);
1110	if( item )
1111	{
1112		mName = item->getName();
1113	}
1114}
1115
1116struct LLWearableSaveData
1117{
1118	LLWearableType::EType mType;
1119};
1120
1121void LLWearable::saveNewAsset() const
1122{
1123//	llinfos << "LLWearable::saveNewAsset() type: " << getTypeName() << llendl;
1124	//llinfos << *this << llendl;
1125
1126	const std::string filename = asset_id_to_filename(mAssetID);
1127	LLFILE* fp = LLFile::fopen(filename, "wb");		/* Flawfinder: ignore */
1128	BOOL successful_save = FALSE;
1129	if(fp && exportFile(fp))
1130	{
1131		successful_save = TRUE;
1132	}
1133	if(fp)
1134	{
1135		fclose(fp);
1136		fp = NULL;
1137	}
1138	if(!successful_save)
1139	{
1140		std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
1141		llwarns << buffer << llendl;
1142		
1143		LLSD args;
1144		args["NAME"] = mName;
1145		LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args);
1146		return;
1147	}
1148
1149	// save it out to database
1150	if( gAssetStorage )
1151	{
1152		 /*
1153		std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
1154		if (!url.empty())
1155		{
1156			llinfos << "Update Agent Inventory via capability" << llendl;
1157			LLSD body;
1158			body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType()));
1159			body["asset_type"] = LLAssetType::lookup(getAssetType());
1160			body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE);
1161			body["name"] = getName();
1162			body["description"] = getDescription();
1163			LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename));
1164		}
1165		else
1166		{
1167		}
1168		 */
1169		 LLWearableSaveData* data = new LLWearableSaveData;
1170		 data->mType = mType;
1171		 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
1172                                     &LLWearable::onSaveNewAssetComplete,
1173                                     (void*)data);
1174	}
1175}
1176
1177// static
1178void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
1179{
1180	LLWearableSaveData* data = (LLWearableSaveData*)userdata;
1181	const std::string& type_name = LLWearableType::getTypeName(data->mType);
1182	if(0 == status)
1183	{
1184		// Success
1185		llinfos << "Saved wearable " << type_name << llendl;
1186	}
1187	else
1188	{
1189		std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str());
1190		llwarns << buffer << " Status: " << status << llendl;
1191		LLSD args;
1192		args["NAME"] = type_name;
1193		LLNotificationsUtil::add("CannotSaveToAssetStore", args);
1194	}
1195
1196	// Delete temp file
1197	const std::string src_filename = asset_id_to_filename(new_asset_id);
1198	LLFile::remove(src_filename);
1199
1200	// delete the context data
1201	delete data;
1202
1203}
1204
1205std::ostream& operator<<(std::ostream &s, const LLWearable &w)
1206{
1207	s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n";
1208	s << "    Name: " << w.mName << "\n";
1209	s << "    Desc: " << w.mDescription << "\n";
1210	//w.mPermissions
1211	//w.mSaleInfo
1212
1213	s << "    Params:" << "\n";
1214	for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
1215		 iter != w.mVisualParamIndexMap.end(); ++iter)
1216	{
1217		S32 param_id = iter->first;
1218		LLVisualParam *wearable_param = iter->second;
1219		F32 param_weight = wearable_param->getWeight();
1220		s << "        " << param_id << " " << param_weight << "\n";
1221	}
1222
1223	s << "    Textures:" << "\n";
1224	for (LLWearable::te_map_t::const_iterator iter = w.mTEMap.begin();
1225		 iter != w.mTEMap.end(); ++iter)
1226	{
1227		S32 te = iter->first;
1228		const LLUUID& image_id = iter->second->getID();
1229		s << "        " << te << " " << image_id << "\n";
1230	}
1231	return s;
1232}
1233
1234
1235std::string terse_F32_to_string(F32 f)
1236{
1237	std::string r = llformat("%.2f", f);
1238	S32 len = r.length();
1239
1240    // "1.20"  -> "1.2"
1241    // "24.00" -> "24."
1242	while (len > 0 && ('0' == r[len - 1]))
1243	{
1244		r.erase(len-1, 1);
1245		len--;
1246	}
1247	if ('.' == r[len - 1])
1248	{
1249		// "24." -> "24"
1250		r.erase(len-1, 1);
1251	}
1252	else if (('-' == r[0]) && ('0' == r[1]))
1253	{
1254		// "-0.59" -> "-.59"
1255		r.erase(1, 1);
1256	}
1257	else if ('0' == r[0])
1258	{
1259		// "0.59" -> ".59"
1260		r.erase(0, 1);
1261	}
1262	return r;
1263}
1264
1265std::string asset_id_to_filename(const LLUUID &asset_id)
1266{
1267	std::string asset_id_string;
1268	asset_id.toString(asset_id_string);
1269	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl";	
1270	return filename;
1271}