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];
00064
00065 strncpy(filename,gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"genepool.xml").c_str(), sizeof(filename) -1);
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
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
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
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
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
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]->mParamMap[ male_param_id ]);
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]->mParamMap[ male_param_id ]);
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]->mParamMap[ male_param_id ]);
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
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
00317
00318
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
00326 if (param_id != male_param_id)
00327 {
00328
00329 F32* weight1p = arch1->getParam( param_id );
00330 F32 weight1 = weight1p ? *weight1p : param->getDefaultWeight();
00331 F32 net_weight = weight1;
00332
00333 if( arch2 && arch3 )
00334 {
00335 F32* weight2p = arch2->getParam( param_id );
00336 F32 weight2 = weight2p ? *weight2p : param->getDefaultWeight();
00337
00338 F32* weight3p = arch3->getParam( param_id );
00339 F32 weight3 = weight3p ? *weight3p : param->getDefaultWeight();
00340
00341 net_weight = b1 * weight1 + b2 * weight2 + b3 * weight3;
00342 }
00343
00344 param->setAnimationTarget(net_weight, TRUE);
00345 }
00346 }
00347 }
00348
00349
00350 LLAppearance* dominant_arch = arch1;
00351 if( (b2 > b1) && (b2 > b3) )
00352 {
00353 dominant_arch = arch2;
00354 }
00355 else
00356 if( (b3 > b1) && (b3 > b2) )
00357 {
00358 dominant_arch = arch3;
00359 }
00360
00361
00362
00363 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00364 {
00365 if( LLVOAvatar::isTextureIndexBaked( te ) )
00366 {
00367 continue;
00368 }
00369
00370 if( LLVOAvatar::getTEWearableType( te ) == type )
00371 {
00372 LLUUID image_id = dominant_arch->getTexture( te );
00373 if( image_id.isNull() )
00374 {
00375 image_id = LLVOAvatar::getDefaultTEImageID( te );
00376 }
00377
00378 LLViewerImage* image = gImageList.getImage( image_id );
00379 if( image )
00380 {
00381 avatar->setLocTexTE( te, image, TRUE );
00382 }
00383 }
00384 }
00385
00386
00387
00388 avatar->startAppearanceAnimation(TRUE, TRUE);
00389 avatar->updateVisualParams();
00390
00391
00392
00393
00394
00395
00396
00397 avatar->updateMeshTextures();
00398 gAgent.sendAgentSetAppearance();
00399 }