llgenepool.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llgenepool.h"
00035 #include "llxmltree.h"
00036 #include "llvoavatar.h"
00037 #include "lluuid.h"
00038 #include "llagent.h"
00039 #include "llviewervisualparam.h"
00040 #include "llxmltree.h"
00041 #include "llviewerimagelist.h"
00042 #include "llappearance.h"
00043 
00044 #include "lldir.h"
00045 
00046 LLGenePool::LLGenePool()
00047         :
00048         mLoaded( FALSE )
00049 {
00050 }
00051 
00052 LLGenePool::~LLGenePool()
00053 {
00054         for( S32 i = 0; i < mArchetypes.count(); i++ )
00055         {
00056                 delete mArchetypes[i];
00057         }
00058 }
00059 
00060 
00061 BOOL LLGenePool::load()
00062 {
00063         char filename[MAX_PATH]; /*Flawfinder: ignore*/
00064 
00065         strncpy(filename,gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"genepool.xml").c_str(), sizeof(filename) -1);                /*Flawfinder: ignore*/  
00066         filename[sizeof(filename) -1] = '\0';
00067         if( mLoaded )
00068         {
00069                 return TRUE;
00070         }
00071 
00072         LLXmlTree xml_tree;
00073         BOOL success = xml_tree.parseFile( filename, FALSE );
00074         if( !success )
00075         {
00076                 return FALSE;
00077         }
00078 
00079         LLXmlTreeNode* root = xml_tree.getRoot();
00080         if( !root )
00081         {
00082                 return FALSE;
00083         }
00084 
00085         //-------------------------------------------------------------------------
00086         // <linden_genepool version="1.0"> (root)
00087         //-------------------------------------------------------------------------
00088         if( !root->hasName( "linden_genepool" ) )
00089         {
00090                 llwarns << "Invalid linden_genepool file header: " << filename << llendl;
00091                 return FALSE;
00092         }
00093 
00094         LLString version;
00095         static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
00096         if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
00097         {
00098                 llwarns << "Invalid linden_genepool file version: " << version << llendl;
00099                 return FALSE;
00100         }
00101 
00102         //-------------------------------------------------------------------------
00103         // <archetype>
00104         //-------------------------------------------------------------------------
00105         for (LLXmlTreeNode* child = root->getChildByName( "archetype" );
00106                  child;
00107                  child = root->getNextNamedChild())
00108         {
00109                 if( !loadNodeArchetype( child ) )
00110                 {
00111                         return FALSE;
00112                 }
00113         }
00114 
00115         mLoaded = TRUE;
00116         return TRUE;
00117 }
00118 
00119 
00120 //-----------------------------------------------------------------------------
00121 // loadNodeArchetype(): loads <archetype> node from XML tree
00122 //-----------------------------------------------------------------------------
00123 BOOL LLGenePool::loadNodeArchetype( LLXmlTreeNode* node )
00124 {
00125         llassert( node->hasName( "archetype" ) );
00126 
00127         LLAppearance* archetype = new LLAppearance();
00128         BOOL success = TRUE;
00129 
00130         LLVOAvatar* avatar = gAgent.getAvatarObject();
00131         if( !avatar )
00132         {
00133                 delete archetype;
00134                 return FALSE;
00135         }
00136 
00137         LLXmlTreeNode* child;
00138         for (child = node->getChildByName( "param" );
00139                  child;
00140                  child = node->getNextNamedChild())
00141         {
00142                 F32 value;
00143                 static LLStdStringHandle value_string = LLXmlTree::addAttributeString("value");
00144                 if( !child->getFastAttributeF32( value_string, value ) )
00145                 {
00146                         llwarns << "avatar genepool file: <param> missing value attribute" << llendl;
00147                         success = FALSE;
00148                         break;
00149                 }
00150                         
00151                 S32 id;
00152                 static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
00153                 if( !child->getFastAttributeS32( id_string, id ) )
00154                 {
00155                         llwarns << "avatar genepool file: <param> missing id attribute" << llendl;
00156                         success = FALSE;
00157                         break;
00158                 }
00159 
00160                 LLVisualParam* param = avatar->getVisualParam( id );
00161                 if( param )
00162                 {
00163                         archetype->addParam( id, value );
00164                 }
00165                 else
00166                 {
00167                         llwarns << "avatar genepool file: ignoring invalid <param> with id: " << id << llendl;
00168                 }
00169         }
00170         for (child = node->getChildByName( "texture" );
00171                  child;
00172                  child = node->getNextNamedChild())
00173         {
00174                 LLUUID uuid;
00175                 static LLStdStringHandle uuid_string = LLXmlTree::addAttributeString("uuid");
00176                 if( !child->getFastAttributeUUID( uuid_string, uuid ) )
00177                 {
00178                         llwarns << "avatar genepool file: <texture> missing uuid attribute" << llendl;
00179                         success = FALSE;
00180                         break;
00181                 }
00182                         
00183                 S32 te;
00184                 static LLStdStringHandle te_string = LLXmlTree::addAttributeString("te");
00185                 if( !child->getFastAttributeS32( te_string, te ) )
00186                 {
00187                         llwarns << "avatar genepool file: <texture> missing te attribute" << llendl;
00188                         success = FALSE;
00189                         break;
00190                 }
00191 
00192                 archetype->addTexture( te, uuid );
00193         }
00194 
00195         if( success )
00196         {
00197                 mArchetypes.put( archetype );
00198         }
00199         else
00200         {
00201                 delete archetype;
00202         }
00203         return success;
00204 }
00205 
00206 // Creates new parameters for the given wearable and applies them to the avatar.
00207 void LLGenePool::spawn( EWearableType type )
00208 {
00209         LLVOAvatar* avatar = gAgent.getAvatarObject();
00210         if( !avatar )
00211         {
00212                 return;
00213         }
00214         
00215         if( !mLoaded )
00216         {
00217                 if( !load() )
00218                 {
00219                         return;
00220                 }
00221         }
00222 
00223         if( mArchetypes.count() < 1 )
00224         {
00225                 return;
00226         }
00227 
00228         // Only consider archetypes that have the same sex as you have already.
00229         LLVisualParam* male_param = avatar->getVisualParam( "male" );
00230 
00231         if (!male_param)
00232         {
00233                 llwarns << "The hard coded \'male\' parameter passed to avatar->getVisualParam() in LLGenePool::spawn() is no longer valid."
00234                                 << llendl;
00235                 return;
00236         }
00237 
00238         S32 male_param_id = male_param->getID();
00239         F32 sex_weight = male_param->getWeight();
00240 
00241         S32 i = 0;
00242         S32 j = 0;
00243         S32 k = 0;
00244         const S32 MAX_CYCLES = 1000;
00245         S32 cycles = 0;
00246 
00247         F32 cur_sex_weight = 0.f;
00248         do
00249         {
00250                 i = rand() % mArchetypes.count();
00251                 cur_sex_weight = mArchetypes[i]->getParam(male_param_id, 0.f);
00252                 cycles++;
00253                 if (cur_sex_weight != sex_weight)
00254                 {
00255                         break;
00256                 }
00257         } while((cycles < MAX_CYCLES));
00258 
00259         if( cycles >= MAX_CYCLES )
00260         {
00261                 return;
00262         }
00263 
00264         LLAppearance* arch1 = mArchetypes[i];
00265         LLAppearance* arch2 = NULL;
00266         LLAppearance* arch3 = NULL;
00267 
00268         if( mArchetypes.count() > 1 )
00269         {
00270                 cycles = 0;
00271         do
00272         {
00273                 j = rand() % mArchetypes.count();
00274                         cur_sex_weight = mArchetypes[j]->getParam(male_param_id, 0.f);
00275 
00276                         cycles++;
00277                 } while( 
00278                         (cycles < MAX_CYCLES) && 
00279                         ( (i == j) || (cur_sex_weight != sex_weight) )
00280                 );
00281 
00282                 if( cycles >= MAX_CYCLES )
00283                 {
00284                         return;
00285                 }
00286 
00287         arch2 = mArchetypes[j];
00288         }
00289 
00290         if( mArchetypes.count() > 2 )
00291         {
00292                 cycles = 0;
00293         do
00294         {
00295                 k = rand() % mArchetypes.count();
00296                         cur_sex_weight = mArchetypes[k]->getParam(male_param_id, 0.f);
00297                         cycles++;
00298                 } while( 
00299                         (cycles < MAX_CYCLES) && 
00300                         ( (i == k) || (j == k) || (cur_sex_weight != sex_weight) )
00301                 );
00302 
00303                 if( cycles >= MAX_CYCLES )
00304                 {
00305                         return;
00306                 }
00307 
00308         arch3 = mArchetypes[k];
00309         }
00310 
00311         // Lame generation of barycentric coordinates
00312         F32 b1 = F32( rand() ) / RAND_MAX;
00313         F32 b2 = (F32( rand() ) / RAND_MAX) * (1.f - b1);
00314         F32 b3 = 1.f - b1 - b2;
00315 
00316 //      ESex old_sex = avatar->getSex();
00317 
00318         // Pull params
00319         for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
00320         {
00321                 if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) )
00322                 {
00323                         S32 param_id = param->getID();
00324 
00325                         // don't try to blend male/female param...as fp innaccuracy will break the [0 | 1] semantics
00326                         if (param_id != male_param_id)
00327                         {
00328 
00329                                 F32 weight1 = arch1->getParam( param_id, param->getDefaultWeight() );
00330                                 F32 net_weight = weight1;
00331                                 
00332                                 if( arch2 && arch3 )
00333                                 {
00334                                 F32 weight2 = arch2->getParam( param_id, param->getDefaultWeight() );
00335                                 F32 weight3 = arch3->getParam( param_id, param->getDefaultWeight() );
00336                                         net_weight = b1 * weight1 + b2 * weight2 + b3 * weight3;
00337                                 }
00338                         
00339                                 param->setAnimationTarget(net_weight, TRUE);
00340                         }
00341                 }
00342         }
00343 
00344         // Find the archetype with the greatest influence
00345         LLAppearance* dominant_arch = arch1;
00346         if( (b2 > b1) && (b2 > b3) )
00347         {
00348                 dominant_arch = arch2;
00349         }
00350         else
00351         if( (b3 > b1) && (b3 > b2) )
00352         {
00353                 dominant_arch = arch3;
00354         }
00355 
00356 
00357         // Pull Textures from the dominant archetype
00358         for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00359         {
00360                 if( LLVOAvatar::isTextureIndexBaked( te ) )
00361                 {
00362                         continue;
00363                 }
00364 
00365                 if( LLVOAvatar::getTEWearableType( te ) == type )
00366                 {
00367                         LLUUID image_id = dominant_arch->getTexture( te );
00368                         if( image_id.isNull() )
00369                         {
00370                                 image_id = LLVOAvatar::getDefaultTEImageID( te );
00371                         }
00372 
00373                         LLViewerImage* image = gImageList.getImage( image_id );
00374                         if( image )
00375                         {
00376                                 avatar->setLocTexTE( te, image, TRUE );
00377                         }
00378                 }
00379         }
00380 
00381 //      avatar->setVisualParamWeight( "male", sex_weight );
00382 
00383         avatar->startAppearanceAnimation(TRUE, TRUE);
00384         avatar->updateVisualParams();
00385 
00386 //      ESex new_sex = avatar->getSex();
00387 //      if( old_sex != new_sex )
00388 //      {
00389 //              avatar->updateSexDependentLayerSets( TRUE );
00390 //      }       
00391         
00392         avatar->updateMeshTextures();
00393     gAgent.sendAgentSetAppearance();
00394 }

Generated on Fri May 16 08:33:36 2008 for SecondLife by  doxygen 1.5.5