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

Generated on Fri May 16 08:34:24 2008 for SecondLife by  doxygen 1.5.5