llwearable.cpp

Go to the documentation of this file.
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 //#include "viewer.h"
00052 //#include "llvfs.h"
00053 
00054 // static
00055 S32 LLWearable::sCurrentDefinitionVersion = 1;
00056 
00057 // static
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 // static
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 // static
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 // static
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] )            /* Flawfinder: ignore */
00158 {
00159         char* r = s;
00160         S32 len = snprintf( s, MAX_STRING, "%.2f", f );         /* Flawfinder: ignore */
00161 
00162         // "1.20"  -> "1.2"
00163         // "24.00" -> "24."
00164         while( '0' == r[len - 1] )
00165         {
00166                 len--;  
00167                 r[len] = '\0';
00168         }
00169 
00170         if( '.' == r[len - 1] )
00171         {
00172                 // "24." -> "24"
00173                 len--;
00174                 r[len] = '\0';
00175         }
00176         else
00177         if( ('-' == r[0]) && ('0' == r[1]) )
00178         {
00179                 // "-0.59" -> "-.59"
00180                 r++;
00181                 r[0] = '-';
00182         }
00183         else
00184         if( '0' == r[0] )
00185         {
00186                 // "0.59" -> ".59"
00187                 r++;
00188         }
00189 
00190         return r;
00191 }
00192 
00193 BOOL LLWearable::exportFile( FILE* file )
00194 {
00195         // header and version
00196         if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
00197         {
00198                 return FALSE;
00199         }
00200 
00201         // name
00202         if( fprintf( file, "%s\n", mName.c_str() ) < 0 )
00203         {
00204                 return FALSE;
00205         }
00206 
00207         // description
00208         if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 )
00209         {
00210                 return FALSE;
00211         }
00212         
00213         // permissions
00214         if( !mPermissions.exportFile( file ) )
00215         {
00216                 return FALSE;
00217         }
00218 
00219         // sale info
00220         if( !mSaleInfo.exportFile( file ) )
00221         {
00222                 return FALSE;
00223         }
00224 
00225         // wearable type
00226         S32 type = (S32)mType;
00227         if( fprintf( file, "type %d\n", type ) < 0 )
00228         {
00229                 return FALSE;
00230         }
00231 
00232         // parameters
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 ];           /* Flawfinder: ignore */
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         // texture entries
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];          /* Flawfinder: ignore */
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         // *NOTE: changing the type or size of this buffer will require
00275         // changes in the fscanf() code below. You would be better off
00276         // rewriting this to use streams and not require an open FILE.
00277         char text_buffer[2048];         /* Flawfinder: ignore */
00278         S32 fields_read = 0;
00279 
00280         // read header and version 
00281         fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion );
00282         if( fields_read != 1 )
00283         {
00284                 // Shouldn't really log the asset id for security reasons, but
00285                 // we need it in this case.
00286                 llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
00287                 //gVFS->dumpMap();
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         // name
00298         char next_char = fgetc( file );         /* Flawfinder: ignore */
00299         if( '\n' == next_char )
00300         {
00301                 // no name
00302                 mName = "";
00303         }
00304         else
00305         {
00306                 ungetc( next_char, file );
00307                 fields_read = fscanf(   /* Flawfinder: ignore */
00308                         file,
00309                         "%2047[^\n]",
00310                         text_buffer);
00311                 if( (1 != fields_read) || (fgetc( file ) != '\n') )             /* Flawfinder: ignore */
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         // description
00321         next_char = fgetc( file );              /* Flawfinder: ignore */
00322         if( '\n' == next_char )
00323         {
00324                 // no description
00325                 mDescription = "";
00326         }
00327         else
00328         {
00329                 ungetc( next_char, file );
00330                 fields_read = fscanf(   /* Flawfinder: ignore */
00331                         file,
00332                         "%2047[^\n]",
00333                         text_buffer );
00334                 if( (1 != fields_read) || (fgetc( file ) != '\n') )             /* Flawfinder: ignore */
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         // permissions
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         // sale info
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         // Sale info used to contain next owner perm. It is now in the
00365         // permissions. Thus, we read that out, and fix legacy
00366         // objects. It's possible this op would fail, but it should pick
00367         // up the vast majority of the tasks.
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                 // fair use fix.
00377                 if(!(perm_mask & PERM_COPY))
00378                 {
00379                         perm_mask |= PERM_TRANSFER;
00380                 }
00381                 mPermissions.setMaskNext(perm_mask);
00382         }
00383 
00384         // wearable type
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         // parameters header
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         // parameters
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", &param_id, &param_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         // textures header
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         // textures
00437         for( i = 0; i < num_textures; i++ )
00438         {
00439                 S32 te = 0;
00440                 fields_read = fscanf(   /* Flawfinder: ignore */
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 // Avatar parameter and texture definitions can change over time.
00464 // This function returns true if parameters or textures have been added or removed
00465 // since this wearable was created.
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 // Avatar parameter and texture definitions can change over time.
00527 // * If parameters or textures have been REMOVED since the wearable was created,
00528 // they're just ignored, so we consider the wearable clean even though isOldVersion()
00529 // will return true. 
00530 // * If parameters or textures have been ADDED since the wearable was created,
00531 // they are taken to have default values, so we consider the wearable clean
00532 // only if those values are the same as the defaults.
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         //if( gFloaterCustomize )
00589         //{
00590         //      if( mDescription != gFloaterCustomize->getWearableDescription( mType ) )
00591         //      {
00592         //              return TRUE;
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 // Updates the user's avatar's appearance
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         // Pull params
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                                 // only animate with user-originated changes
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                                 // only animate with user-originated changes
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         // only interpolate with user-originated changes
00678         if (set_by_user)
00679         {
00680                 avatar->startAppearanceAnimation(TRUE, TRUE);
00681         }
00682 
00683         // Pull texture entries
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 //      if( set_by_user )
00725 //      {
00726 //              gAgent.sendAgentSetAppearance();
00727 //      }
00728 }
00729 
00730 // Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values.
00731 // static 
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         // You can't just remove body parts.
00742         if( (type == WT_SHAPE) ||
00743                 (type == WT_SKIN) ||
00744                 (type == WT_HAIR) ||
00745                 (type == WT_EYES) )
00746         {
00747                 return;
00748         }
00749 
00750         // Pull params
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         // Pull textures
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 //      if( set_by_user )
00779 //      {
00780 //              gAgent.sendAgentSetAppearance();
00781 //      }
00782 }
00783 
00784 
00785 
00786 // Updates asset from the user's avatar
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         //if( gFloaterCustomize )
00821         //{
00822         //      mDescription = gFloaterCustomize->getWearableDescription( mType );
00823         //}
00824 }
00825 
00826 // Does not copy mAssetID.
00827 // Definition version is current: removes obsolete enties and creates default values for new ones.
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         // Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed)
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         // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
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 //      llinfos << "LLWearable::saveNewAsset() type: " << getTypeName() << llendl;
00879         //dump();
00880 
00881         char new_asset_id_string[UUID_STR_LENGTH];              /* Flawfinder: ignore */
00882         mAssetID.toString(new_asset_id_string);
00883         char filename[LL_MAX_PATH];             /* Flawfinder: ignore */
00884         snprintf(filename, LL_MAX_PATH, "%s.wbl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,new_asset_id_string).c_str());           /* Flawfinder: ignore */
00885         FILE* fp = LLFile::fopen(filename, "wb");               /* Flawfinder: ignore */
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];              /* Flawfinder: ignore */
00899                 snprintf(buffer,                /* Flawfinder: ignore */
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         // save it out to database
00912         if( gAssetStorage )
00913         {
00914                  /*
00915                 std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
00916                 if (!url.empty())
00917                 {
00918                         llinfos << "Update Agent Inventory via capability" << llendl;
00919                         LLSD body;
00920                         body["folder_id"] = gInventory.findCategoryUUIDForType(getAssetType());
00921                         body["asset_type"] = LLAssetType::lookup(getAssetType());
00922                         body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE);
00923                         body["name"] = getName();
00924                         body["description"] = getDescription();
00925                         LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename));
00926                 }
00927                 else
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 // static
00940 void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
00941 {
00942         LLWearableSaveData* data = (LLWearableSaveData*)userdata;
00943         const char* type_name = LLWearable::typeToTypeName(data->mType);
00944         if(0 == status)
00945         {
00946                 // Success
00947                 llinfos << "Saved wearable " << type_name << llendl;
00948         }
00949         else
00950         {
00951                 char buffer[2*MAX_STRING];              /* Flawfinder: ignore */
00952                 snprintf(buffer,                /* Flawfinder: ignore */
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         // Delete temp file
00963         char new_asset_id_string[UUID_STR_LENGTH];              /* Flawfinder: ignore */
00964         new_asset_id.toString(new_asset_id_string);
00965         char src_filename[LL_MAX_PATH];         /* Flawfinder: ignore */
00966         snprintf(src_filename, LL_MAX_PATH, "%s.wbl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,new_asset_id_string).c_str());               /* Flawfinder: ignore */
00967         LLFile::remove(src_filename);
00968 
00969         // delete the context data
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         //mPermissions
00988         //mSaleInfo
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 

Generated on Thu Jul 1 06:09:45 2010 for Second Life Viewer by  doxygen 1.4.7