00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "imageids.h"
00035 #include "llassetstorage.h"
00036 #include "lldbstrings.h"
00037 #include "lldir.h"
00038 #include "llquantize.h"
00039
00040 #include "llagent.h"
00041 #include "llassetuploadresponders.h"
00042 #include "llviewerwindow.h"
00043 #include "llfloatercustomize.h"
00044 #include "llinventorymodel.h"
00045 #include "llviewerimagelist.h"
00046 #include "llviewerinventory.h"
00047 #include "llviewerregion.h"
00048 #include "llvoavatar.h"
00049 #include "llwearable.h"
00050
00051
00052
00053
00054
00055 S32 LLWearable::sCurrentDefinitionVersion = 1;
00056
00057
00058 const char* LLWearable::sTypeName[ WT_COUNT ] =
00059 {
00060 "shape",
00061 "skin",
00062 "hair",
00063 "eyes",
00064 "shirt",
00065 "pants",
00066 "shoes",
00067 "socks",
00068 "jacket",
00069 "gloves",
00070 "undershirt",
00071 "underpants",
00072 "skirt"
00073 };
00074
00075
00076 const char* LLWearable::sTypeLabel[ WT_COUNT ] =
00077 {
00078 "Shape",
00079 "Skin",
00080 "Hair",
00081 "Eyes",
00082 "Shirt",
00083 "Pants",
00084 "Shoes",
00085 "Socks",
00086 "Jacket",
00087 "Gloves",
00088 "Undershirt",
00089 "Underpants",
00090 "Skirt"
00091 };
00092
00093
00094
00095 LLAssetType::EType LLWearable::typeToAssetType(EWearableType wearable_type)
00096 {
00097 switch( wearable_type )
00098 {
00099 case WT_SHAPE:
00100 case WT_SKIN:
00101 case WT_HAIR:
00102 case WT_EYES:
00103 return LLAssetType::AT_BODYPART;
00104 case WT_SHIRT:
00105 case WT_PANTS:
00106 case WT_SHOES:
00107 case WT_SOCKS:
00108 case WT_JACKET:
00109 case WT_GLOVES:
00110 case WT_UNDERSHIRT:
00111 case WT_UNDERPANTS:
00112 case WT_SKIRT:
00113 return LLAssetType::AT_CLOTHING;
00114 default:
00115 return LLAssetType::AT_NONE;
00116 }
00117 }
00118
00119
00120 LLWearable::LLWearable(const LLTransactionID& transaction_id) :
00121 mDefinitionVersion(LLWearable::sCurrentDefinitionVersion),
00122 mType(WT_SHAPE)
00123 {
00124 mTransactionID = transaction_id;
00125 mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
00126 }
00127
00128 LLWearable::LLWearable(const LLAssetID& asset_id) :
00129 mDefinitionVersion( LLWearable::sCurrentDefinitionVersion ),
00130 mType(WT_SHAPE)
00131 {
00132 mAssetID = asset_id;
00133 mTransactionID.setNull();
00134 }
00135
00136 LLWearable::~LLWearable()
00137 {
00138 mVisualParamMap.deleteAllData();
00139 mTEMap.deleteAllData();
00140 }
00141
00142
00143
00144 EWearableType LLWearable::typeNameToType( const LLString& type_name )
00145 {
00146 for( S32 i = 0; i < WT_COUNT; i++ )
00147 {
00148 if( type_name == LLWearable::sTypeName[ i ] )
00149 {
00150 return (EWearableType)i;
00151 }
00152 }
00153 return WT_INVALID;
00154 }
00155
00156
00157 const char* terse_F32_to_string( F32 f, char s[MAX_STRING] )
00158 {
00159 char* r = s;
00160 S32 len = snprintf( s, MAX_STRING, "%.2f", f );
00161
00162
00163
00164 while( '0' == r[len - 1] )
00165 {
00166 len--;
00167 r[len] = '\0';
00168 }
00169
00170 if( '.' == r[len - 1] )
00171 {
00172
00173 len--;
00174 r[len] = '\0';
00175 }
00176 else
00177 if( ('-' == r[0]) && ('0' == r[1]) )
00178 {
00179
00180 r++;
00181 r[0] = '-';
00182 }
00183 else
00184 if( '0' == r[0] )
00185 {
00186
00187 r++;
00188 }
00189
00190 return r;
00191 }
00192
00193 BOOL LLWearable::exportFile( FILE* file )
00194 {
00195
00196 if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
00197 {
00198 return FALSE;
00199 }
00200
00201
00202 if( fprintf( file, "%s\n", mName.c_str() ) < 0 )
00203 {
00204 return FALSE;
00205 }
00206
00207
00208 if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 )
00209 {
00210 return FALSE;
00211 }
00212
00213
00214 if( !mPermissions.exportFile( file ) )
00215 {
00216 return FALSE;
00217 }
00218
00219
00220 if( !mSaleInfo.exportFile( file ) )
00221 {
00222 return FALSE;
00223 }
00224
00225
00226 S32 type = (S32)mType;
00227 if( fprintf( file, "type %d\n", type ) < 0 )
00228 {
00229 return FALSE;
00230 }
00231
00232
00233 S32 num_parameters = mVisualParamMap.getLength();
00234 if( fprintf( file, "parameters %d\n", num_parameters ) < 0 )
00235 {
00236 return FALSE;
00237 }
00238
00239 char s[ MAX_STRING ];
00240 for( F32* param_weightp = mVisualParamMap.getFirstData(); param_weightp; param_weightp = mVisualParamMap.getNextData() )
00241 {
00242 S32 param_id = mVisualParamMap.getCurrentKeyWithoutIncrement();
00243 if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( *param_weightp, s ) ) < 0 )
00244 {
00245 return FALSE;
00246 }
00247 }
00248
00249
00250 S32 num_textures = mTEMap.getLength();
00251 if( fprintf( file, "textures %d\n", num_textures ) < 0 )
00252 {
00253 return FALSE;
00254 }
00255
00256 for( LLUUID* image_id = mTEMap.getFirstData(); image_id; image_id = mTEMap.getNextData() )
00257 {
00258 S32 te = mTEMap.getCurrentKeyWithoutIncrement();
00259 char image_id_string[UUID_STR_LENGTH];
00260 image_id->toString( image_id_string );
00261 if( fprintf( file, "%d %s\n", te, image_id_string) < 0 )
00262 {
00263 return FALSE;
00264 }
00265 }
00266
00267 return TRUE;
00268 }
00269
00270
00271
00272 BOOL LLWearable::importFile( FILE* file )
00273 {
00274
00275
00276
00277 char text_buffer[2048];
00278 S32 fields_read = 0;
00279
00280
00281 fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion );
00282 if( fields_read != 1 )
00283 {
00284
00285
00286 llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
00287
00288 return FALSE;
00289 }
00290
00291 if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion )
00292 {
00293 llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
00294 return FALSE;
00295 }
00296
00297
00298 char next_char = fgetc( file );
00299 if( '\n' == next_char )
00300 {
00301
00302 mName = "";
00303 }
00304 else
00305 {
00306 ungetc( next_char, file );
00307 fields_read = fscanf(
00308 file,
00309 "%2047[^\n]",
00310 text_buffer);
00311 if( (1 != fields_read) || (fgetc( file ) != '\n') )
00312 {
00313 llwarns << "Bad Wearable asset: early end of file" << llendl;
00314 return FALSE;
00315 }
00316 mName = text_buffer;
00317 LLString::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
00318 }
00319
00320
00321 next_char = fgetc( file );
00322 if( '\n' == next_char )
00323 {
00324
00325 mDescription = "";
00326 }
00327 else
00328 {
00329 ungetc( next_char, file );
00330 fields_read = fscanf(
00331 file,
00332 "%2047[^\n]",
00333 text_buffer );
00334 if( (1 != fields_read) || (fgetc( file ) != '\n') )
00335 {
00336 llwarns << "Bad Wearable asset: early end of file" << llendl;
00337 return FALSE;
00338 }
00339 mDescription = text_buffer;
00340 LLString::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
00341 }
00342
00343
00344 S32 perm_version;
00345 fields_read = fscanf( file, " permissions %d\n", &perm_version );
00346 if( (fields_read != 1) || (perm_version != 0) )
00347 {
00348 llwarns << "Bad Wearable asset: missing permissions" << llendl;
00349 return FALSE;
00350 }
00351 if( !mPermissions.importFile( file ) )
00352 {
00353 return FALSE;
00354 }
00355
00356
00357 S32 sale_info_version;
00358 fields_read = fscanf( file, " sale_info %d\n", &sale_info_version );
00359 if( (fields_read != 1) || (sale_info_version != 0) )
00360 {
00361 llwarns << "Bad Wearable asset: missing sale_info" << llendl;
00362 return FALSE;
00363 }
00364
00365
00366
00367
00368 BOOL has_perm_mask = FALSE;
00369 U32 perm_mask = 0;
00370 if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) )
00371 {
00372 return FALSE;
00373 }
00374 if(has_perm_mask)
00375 {
00376
00377 if(!(perm_mask & PERM_COPY))
00378 {
00379 perm_mask |= PERM_TRANSFER;
00380 }
00381 mPermissions.setMaskNext(perm_mask);
00382 }
00383
00384
00385 S32 type = -1;
00386 fields_read = fscanf( file, "type %d\n", &type );
00387 if( fields_read != 1 )
00388 {
00389 llwarns << "Bad Wearable asset: bad type" << llendl;
00390 return FALSE;
00391 }
00392 if( 0 <= type && type < WT_COUNT )
00393 {
00394 mType = (EWearableType)type;
00395 }
00396 else
00397 {
00398 llwarns << "Bad Wearable asset: bad type #" << type << llendl;
00399 return FALSE;
00400 }
00401
00402
00403
00404 S32 num_parameters = 0;
00405 fields_read = fscanf( file, "parameters %d\n", &num_parameters );
00406 if( fields_read != 1 )
00407 {
00408 llwarns << "Bad Wearable asset: missing parameters block" << llendl;
00409 return FALSE;
00410 }
00411
00412
00413 S32 i;
00414 for( i = 0; i < num_parameters; i++ )
00415 {
00416 S32 param_id = 0;
00417 F32 param_weight = 0.f;
00418 fields_read = fscanf( file, "%d %f\n", ¶m_id, ¶m_weight );
00419 if( fields_read != 2 )
00420 {
00421 llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
00422 return FALSE;
00423 }
00424 mVisualParamMap.addData( param_id, new F32(param_weight) );
00425 }
00426
00427
00428 S32 num_textures = 0;
00429 fields_read = fscanf( file, "textures %d\n", &num_textures);
00430 if( fields_read != 1 )
00431 {
00432 llwarns << "Bad Wearable asset: missing textures block" << llendl;
00433 return FALSE;
00434 }
00435
00436
00437 for( i = 0; i < num_textures; i++ )
00438 {
00439 S32 te = 0;
00440 fields_read = fscanf(
00441 file,
00442 "%d %2047s\n",
00443 &te, text_buffer);
00444 if( fields_read != 2 )
00445 {
00446 llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
00447 return FALSE;
00448 }
00449
00450 if( !LLUUID::validate( text_buffer ) )
00451 {
00452 llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
00453 return FALSE;
00454 }
00455
00456 mTEMap.addData( te, new LLUUID( text_buffer ) );
00457 }
00458
00459 return TRUE;
00460 }
00461
00462
00463
00464
00465
00466 BOOL LLWearable::isOldVersion()
00467 {
00468 LLVOAvatar* avatar = gAgent.getAvatarObject();
00469 llassert( avatar );
00470 if( !avatar )
00471 {
00472 return FALSE;
00473 }
00474
00475 if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
00476 {
00477 llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
00478 llassert(0);
00479 }
00480
00481 if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
00482 {
00483 return TRUE;
00484 }
00485
00486 S32 param_count = 0;
00487 for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam();
00488 param;
00489 param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
00490 {
00491 if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00492 {
00493 param_count++;
00494 if( !mVisualParamMap.checkKey( param->getID() ) )
00495 {
00496 return TRUE;
00497 }
00498 }
00499 }
00500 if( param_count != mVisualParamMap.getLength() )
00501 {
00502 return TRUE;
00503 }
00504
00505
00506 S32 te_count = 0;
00507 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00508 {
00509 if( LLVOAvatar::getTEWearableType( te ) == mType )
00510 {
00511 te_count++;
00512 if( !mTEMap.checkKey( te ) )
00513 {
00514 return TRUE;
00515 }
00516 }
00517 }
00518 if( te_count != mTEMap.getLength() )
00519 {
00520 return TRUE;
00521 }
00522
00523 return FALSE;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533 BOOL LLWearable::isDirty()
00534 {
00535 LLVOAvatar* avatar = gAgent.getAvatarObject();
00536 llassert( avatar );
00537 if( !avatar )
00538 {
00539 return FALSE;
00540 }
00541
00542
00543 for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam();
00544 param;
00545 param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
00546 {
00547 if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00548 {
00549 F32* weightp = mVisualParamMap.getIfThere( param->getID() );
00550 F32 weight;
00551 if( weightp )
00552 {
00553 weight = llclamp( *weightp, param->getMinWeight(), param->getMaxWeight() );
00554 }
00555 else
00556 {
00557 weight = param->getDefaultWeight();
00558 }
00559
00560 U8 a = F32_to_U8( param->getWeight(), param->getMinWeight(), param->getMaxWeight() );
00561 U8 b = F32_to_U8( weight, param->getMinWeight(), param->getMaxWeight() );
00562 if( a != b )
00563 {
00564 return TRUE;
00565 }
00566 }
00567 }
00568
00569 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00570 {
00571 if( LLVOAvatar::getTEWearableType( te ) == mType )
00572 {
00573 LLViewerImage* avatar_image = avatar->getTEImage( te );
00574 if( !avatar_image )
00575 {
00576 llassert( 0 );
00577 continue;
00578 }
00579 LLUUID* mapped_image_id = mTEMap.getIfThere( te );
00580 const LLUUID& image_id = mapped_image_id ? *mapped_image_id : LLVOAvatar::getDefaultTEImageID( te );
00581 if( avatar_image->getID() != image_id )
00582 {
00583 return TRUE;
00584 }
00585 }
00586 }
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 return FALSE;
00597 }
00598
00599
00600 void LLWearable::setParamsToDefaults()
00601 {
00602 LLVOAvatar* avatar = gAgent.getAvatarObject();
00603 llassert( avatar );
00604 if( !avatar )
00605 {
00606 return;
00607 }
00608
00609 mVisualParamMap.deleteAllData();
00610 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
00611 {
00612 if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00613 {
00614 mVisualParamMap.addData( param->getID(), new F32( param->getDefaultWeight() ) );
00615 }
00616 }
00617 }
00618
00619 void LLWearable::setTexturesToDefaults()
00620 {
00621 mTEMap.deleteAllData();
00622 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00623 {
00624 if( LLVOAvatar::getTEWearableType( te ) == mType )
00625 {
00626 mTEMap.addData( te, new LLUUID( LLVOAvatar::getDefaultTEImageID( te ) ) );
00627 }
00628 }
00629 }
00630
00631
00632 void LLWearable::writeToAvatar( BOOL set_by_user )
00633 {
00634 LLVOAvatar* avatar = gAgent.getAvatarObject();
00635 llassert( avatar );
00636 if( !avatar )
00637 {
00638 return;
00639 }
00640
00641 ESex old_sex = avatar->getSex();
00642
00643
00644 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
00645 {
00646 if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00647 {
00648 S32 param_id = param->getID();
00649 F32* weight = mVisualParamMap.getIfThere( param_id );
00650 if( weight )
00651 {
00652
00653 if (set_by_user)
00654 {
00655 param->setAnimationTarget(*weight, set_by_user);
00656 }
00657 else
00658 {
00659 avatar->setVisualParamWeight( param_id, *weight, set_by_user );
00660 }
00661 }
00662 else
00663 {
00664
00665 if (set_by_user)
00666 {
00667 param->setAnimationTarget(param->getDefaultWeight(), set_by_user);
00668 }
00669 else
00670 {
00671 avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), set_by_user );
00672 }
00673 }
00674 }
00675 }
00676
00677
00678 if (set_by_user)
00679 {
00680 avatar->startAppearanceAnimation(TRUE, TRUE);
00681 }
00682
00683
00684 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00685 {
00686 if( LLVOAvatar::getTEWearableType( te ) == mType )
00687 {
00688 LLUUID* mapped_image_id = mTEMap.getIfThere( te );
00689 const LLUUID& image_id = mapped_image_id ? *mapped_image_id : LLVOAvatar::getDefaultTEImageID( te );
00690 LLViewerImage* image = gImageList.getImage( image_id );
00691 avatar->setLocTexTE( te, image, set_by_user );
00692 }
00693 }
00694
00695 avatar->updateVisualParams();
00696
00697 if( gFloaterCustomize )
00698 {
00699 LLViewerInventoryItem* item;
00700 item = (LLViewerInventoryItem*)gInventory.getItem(gAgent.getWearableItem(mType));
00701 U32 perm_mask = PERM_NONE;
00702 BOOL is_complete = FALSE;
00703 if(item)
00704 {
00705 perm_mask = item->getPermissions().getMaskOwner();
00706 is_complete = item->isComplete();
00707 if(!is_complete)
00708 {
00709 item->fetchFromServer();
00710 }
00711 }
00712 gFloaterCustomize->setWearable(mType, this, perm_mask, is_complete);
00713 LLFloaterCustomize::setCurrentWearableType( mType );
00714 }
00715
00716 ESex new_sex = avatar->getSex();
00717 if( old_sex != new_sex )
00718 {
00719 avatar->updateSexDependentLayerSets( set_by_user );
00720 }
00721
00722 avatar->updateMeshTextures();
00723
00724
00725
00726
00727
00728 }
00729
00730
00731
00732 void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user )
00733 {
00734 LLVOAvatar* avatar = gAgent.getAvatarObject();
00735 llassert( avatar );
00736 if( !avatar )
00737 {
00738 return;
00739 }
00740
00741
00742 if( (type == WT_SHAPE) ||
00743 (type == WT_SKIN) ||
00744 (type == WT_HAIR) ||
00745 (type == WT_EYES) )
00746 {
00747 return;
00748 }
00749
00750
00751 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
00752 {
00753 if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00754 {
00755 S32 param_id = param->getID();
00756 avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), set_by_user );
00757 }
00758 }
00759
00760
00761 LLViewerImage* image = gImageList.getImage( IMG_DEFAULT_AVATAR );
00762 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00763 {
00764 if( LLVOAvatar::getTEWearableType( te ) == type )
00765 {
00766 avatar->setLocTexTE( te, image, set_by_user );
00767 }
00768 }
00769
00770 if( gFloaterCustomize )
00771 {
00772 gFloaterCustomize->setWearable(type, NULL, PERM_ALL, TRUE);
00773 }
00774
00775 avatar->updateVisualParams();
00776 avatar->updateMeshTextures();
00777
00778
00779
00780
00781
00782 }
00783
00784
00785
00786
00787 void LLWearable::readFromAvatar()
00788 {
00789 LLVOAvatar* avatar = gAgent.getAvatarObject();
00790 llassert( avatar );
00791 if( !avatar )
00792 {
00793 return;
00794 }
00795
00796 mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
00797
00798 mVisualParamMap.deleteAllData();
00799 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
00800 {
00801 if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00802 {
00803 mVisualParamMap.addData( param->getID(), new F32( param->getWeight() ) );
00804 }
00805 }
00806
00807 mTEMap.deleteAllData();
00808 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00809 {
00810 if( LLVOAvatar::getTEWearableType( te ) == mType )
00811 {
00812 LLViewerImage* image = avatar->getTEImage( te );
00813 if( image )
00814 {
00815 mTEMap.addData( te, new LLUUID( image->getID() ) );
00816 }
00817 }
00818 }
00819
00820
00821
00822
00823
00824 }
00825
00826
00827
00828 void LLWearable::copyDataFrom( LLWearable* src )
00829 {
00830 LLVOAvatar* avatar = gAgent.getAvatarObject();
00831 llassert( avatar );
00832 if( !avatar )
00833 {
00834 return;
00835 }
00836
00837 mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
00838
00839 mName = src->mName;
00840 mDescription = src->mDescription;
00841 mPermissions = src->mPermissions;
00842 mSaleInfo = src->mSaleInfo;
00843 mType = src->mType;
00844
00845
00846 for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam();
00847 param;
00848 param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
00849 {
00850 if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00851 {
00852 S32 id = param->getID();
00853 F32* weightp = src->mVisualParamMap.getIfThere( id );
00854 F32 weight = weightp ? *weightp : param->getDefaultWeight();
00855 mVisualParamMap.addData( id, new F32( weight ) );
00856 }
00857 }
00858
00859
00860 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00861 {
00862 if( LLVOAvatar::getTEWearableType( te ) == mType )
00863 {
00864 LLUUID* mapped_image_id = src->mTEMap.getIfThere( te );
00865 const LLUUID& image_id = mapped_image_id ? *mapped_image_id : LLVOAvatar::getDefaultTEImageID( te );
00866 mTEMap.addData( te, new LLUUID( image_id ) );
00867 }
00868 }
00869 }
00870
00871 struct LLWearableSaveData
00872 {
00873 EWearableType mType;
00874 };
00875
00876 void LLWearable::saveNewAsset()
00877 {
00878
00879
00880
00881 char new_asset_id_string[UUID_STR_LENGTH];
00882 mAssetID.toString(new_asset_id_string);
00883 char filename[LL_MAX_PATH];
00884 snprintf(filename, LL_MAX_PATH, "%s.wbl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,new_asset_id_string).c_str());
00885 FILE* fp = LLFile::fopen(filename, "wb");
00886 BOOL successful_save = FALSE;
00887 if(fp && exportFile(fp))
00888 {
00889 successful_save = TRUE;
00890 }
00891 if(fp)
00892 {
00893 fclose(fp);
00894 fp = NULL;
00895 }
00896 if(!successful_save)
00897 {
00898 char buffer[2*MAX_STRING];
00899 snprintf(buffer,
00900 sizeof(buffer),
00901 "Unable to save '%s' to wearable file.",
00902 mName.c_str());
00903 llwarns << buffer << llendl;
00904
00905 LLStringBase<char>::format_map_t args;
00906 args["[NAME]"] = mName;
00907 gViewerWindow->alertXml("CannotSaveWearableOutOfSpace", args);
00908 return;
00909 }
00910
00911
00912 if( gAssetStorage )
00913 {
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 LLWearableSaveData* data = new LLWearableSaveData;
00932 data->mType = mType;
00933 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
00934 &LLWearable::onSaveNewAssetComplete,
00935 (void*)data);
00936 }
00937 }
00938
00939
00940 void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status)
00941 {
00942 LLWearableSaveData* data = (LLWearableSaveData*)userdata;
00943 const char* type_name = LLWearable::typeToTypeName(data->mType);
00944 if(0 == status)
00945 {
00946
00947 llinfos << "Saved wearable " << type_name << llendl;
00948 }
00949 else
00950 {
00951 char buffer[2*MAX_STRING];
00952 snprintf(buffer,
00953 sizeof(buffer),
00954 "Unable to save %s to central asset store.",
00955 type_name);
00956 llwarns << buffer << " Status: " << status << llendl;
00957 LLStringBase<char>::format_map_t args;
00958 args["[NAME]"] = type_name;
00959 gViewerWindow->alertXml("CannotSaveToAssetStore", args);
00960 }
00961
00962
00963 char new_asset_id_string[UUID_STR_LENGTH];
00964 new_asset_id.toString(new_asset_id_string);
00965 char src_filename[LL_MAX_PATH];
00966 snprintf(src_filename, LL_MAX_PATH, "%s.wbl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,new_asset_id_string).c_str());
00967 LLFile::remove(src_filename);
00968
00969
00970 delete data;
00971 }
00972
00973 BOOL LLWearable::isMatchedToInventoryItem( LLViewerInventoryItem* item )
00974 {
00975 return
00976 ( mName == item->getName() ) &&
00977 ( mDescription == item->getDescription() ) &&
00978 ( mPermissions == item->getPermissions() ) &&
00979 ( mSaleInfo == item->getSaleInfo() );
00980 }
00981
00982 void LLWearable::dump()
00983 {
00984 llinfos << "wearable " << LLWearable::typeToTypeName( mType ) << llendl;
00985 llinfos << " Name: " << mName << llendl;
00986 llinfos << " Desc: " << mDescription << llendl;
00987
00988
00989
00990 llinfos << " Params:" << llendl;
00991 for( F32* param_weightp = mVisualParamMap.getFirstData();
00992 param_weightp;
00993 param_weightp = mVisualParamMap.getNextData() )
00994 {
00995 S32 param_id = mVisualParamMap.getCurrentKeyWithoutIncrement();
00996 llinfos << " " << param_id << " " << *param_weightp << llendl;
00997 }
00998
00999 llinfos << " Textures:" << llendl;
01000 for( LLUUID* image_id = mTEMap.getFirstData();
01001 image_id;
01002 image_id = mTEMap.getNextData() )
01003 {
01004 S32 te = mTEMap.getCurrentKeyWithoutIncrement();
01005 llinfos << " " << te << " " << *image_id << llendl;
01006 }
01007 }
01008
01009