aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llgenepool.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llgenepool.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llgenepool.cpp')
-rw-r--r--linden/indra/newview/llgenepool.cpp386
1 files changed, 386 insertions, 0 deletions
diff --git a/linden/indra/newview/llgenepool.cpp b/linden/indra/newview/llgenepool.cpp
new file mode 100644
index 0000000..33cb70d
--- /dev/null
+++ b/linden/indra/newview/llgenepool.cpp
@@ -0,0 +1,386 @@
1/**
2 * @file llgenepool.cpp
3 * @brief LLGenePool class implementation
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "llgenepool.h"
31#include "llxmltree.h"
32#include "llvoavatar.h"
33#include "lluuid.h"
34#include "llagent.h"
35#include "llviewervisualparam.h"
36#include "llxmltree.h"
37#include "llviewerimagelist.h"
38#include "llappearance.h"
39
40#include "lldir.h"
41
42LLGenePool::LLGenePool()
43 :
44 mLoaded( FALSE )
45{
46}
47
48LLGenePool::~LLGenePool()
49{
50 for( S32 i = 0; i < mArchetypes.count(); i++ )
51 {
52 delete mArchetypes[i];
53 }
54}
55
56
57BOOL LLGenePool::load()
58{
59 char filename[MAX_PATH];
60
61 strcpy(filename,gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"genepool.xml").c_str());
62
63 if( mLoaded )
64 {
65 return TRUE;
66 }
67
68 LLXmlTree xml_tree;
69 BOOL success = xml_tree.parseFile( filename, FALSE );
70 if( !success )
71 {
72 return FALSE;
73 }
74
75 LLXmlTreeNode* root = xml_tree.getRoot();
76 if( !root )
77 {
78 return FALSE;
79 }
80
81 //-------------------------------------------------------------------------
82 // <linden_genepool version="1.0"> (root)
83 //-------------------------------------------------------------------------
84 if( !root->hasName( "linden_genepool" ) )
85 {
86 llwarns << "Invalid linden_genepool file header: " << filename << llendl;
87 return FALSE;
88 }
89
90 LLString version;
91 static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
92 if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
93 {
94 llwarns << "Invalid linden_genepool file version: " << version << llendl;
95 return FALSE;
96 }
97
98 //-------------------------------------------------------------------------
99 // <archetype>
100 //-------------------------------------------------------------------------
101 for (LLXmlTreeNode* child = root->getChildByName( "archetype" );
102 child;
103 child = root->getNextNamedChild())
104 {
105 if( !loadNodeArchetype( child ) )
106 {
107 return FALSE;
108 }
109 }
110
111 mLoaded = TRUE;
112 return TRUE;
113}
114
115
116//-----------------------------------------------------------------------------
117// loadNodeArchetype(): loads <archetype> node from XML tree
118//-----------------------------------------------------------------------------
119BOOL LLGenePool::loadNodeArchetype( LLXmlTreeNode* node )
120{
121 llassert( node->hasName( "archetype" ) );
122
123 LLAppearance* archetype = new LLAppearance();
124 BOOL success = TRUE;
125
126 LLVOAvatar* avatar = gAgent.getAvatarObject();
127 if( !avatar )
128 {
129 return FALSE;
130 }
131
132 LLXmlTreeNode* child;
133 for (child = node->getChildByName( "param" );
134 child;
135 child = node->getNextNamedChild())
136 {
137 F32 value;
138 static LLStdStringHandle value_string = LLXmlTree::addAttributeString("value");
139 if( !child->getFastAttributeF32( value_string, value ) )
140 {
141 llwarns << "avatar genepool file: <param> missing value attribute" << llendl;
142 success = FALSE;
143 break;
144 }
145
146 S32 id;
147 static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
148 if( !child->getFastAttributeS32( id_string, id ) )
149 {
150 llwarns << "avatar genepool file: <param> missing id attribute" << llendl;
151 success = FALSE;
152 break;
153 }
154
155 LLVisualParam* param = avatar->getVisualParam( id );
156 if( param )
157 {
158 archetype->addParam( id, value );
159 }
160 else
161 {
162 llwarns << "avatar genepool file: ignoring invalid <param> with id: " << id << llendl;
163 }
164 }
165 for (child = node->getChildByName( "texture" );
166 child;
167 child = node->getNextNamedChild())
168 {
169 LLUUID uuid;
170 static LLStdStringHandle uuid_string = LLXmlTree::addAttributeString("uuid");
171 if( !child->getFastAttributeUUID( uuid_string, uuid ) )
172 {
173 llwarns << "avatar genepool file: <texture> missing uuid attribute" << llendl;
174 success = FALSE;
175 break;
176 }
177
178 S32 te;
179 static LLStdStringHandle te_string = LLXmlTree::addAttributeString("te");
180 if( !child->getFastAttributeS32( te_string, te ) )
181 {
182 llwarns << "avatar genepool file: <texture> missing te attribute" << llendl;
183 success = FALSE;
184 break;
185 }
186
187 archetype->addTexture( te, uuid );
188 }
189
190 if( success )
191 {
192 mArchetypes.put( archetype );
193 }
194 else
195 {
196 delete archetype;
197 }
198 return success;
199}
200
201// Creates new parameters for the given wearable and applies them to the avatar.
202void LLGenePool::spawn( EWearableType type )
203{
204 LLVOAvatar* avatar = gAgent.getAvatarObject();
205 if( !avatar )
206 {
207 return;
208 }
209
210 if( !mLoaded )
211 {
212 if( !load() )
213 {
214 return;
215 }
216 }
217
218 if( mArchetypes.count() < 1 )
219 {
220 return;
221 }
222
223 // Only consider archetypes that have the same sex as you have already.
224 LLVisualParam* male_param = avatar->getVisualParam( "male" );
225 S32 male_param_id = male_param->getID();
226 F32 sex_weight = male_param->getWeight();
227
228 S32 i = 0;
229 S32 j = 0;
230 S32 k = 0;
231 const S32 MAX_CYCLES = 1000;
232 S32 cycles = 0;
233
234 F32 cur_sex_weight = 0.f;
235 do
236 {
237 i = rand() % mArchetypes.count();
238 cur_sex_weight = *(mArchetypes[i]->mParamMap[ male_param_id ]);
239 cycles++;
240 if (cur_sex_weight != sex_weight)
241 {
242 break;
243 }
244 } while((cycles < MAX_CYCLES));
245
246 if( cycles >= MAX_CYCLES )
247 {
248 return;
249 }
250
251 LLAppearance* arch1 = mArchetypes[i];
252 LLAppearance* arch2 = NULL;
253 LLAppearance* arch3 = NULL;
254
255 if( mArchetypes.count() > 1 )
256 {
257 cycles = 0;
258 do
259 {
260 j = rand() % mArchetypes.count();
261 cur_sex_weight = *(mArchetypes[j]->mParamMap[ male_param_id ]);
262
263 cycles++;
264 } while(
265 (cycles < MAX_CYCLES) &&
266 ( (i == j) || (cur_sex_weight != sex_weight) )
267 );
268
269 if( cycles >= MAX_CYCLES )
270 {
271 return;
272 }
273
274 arch2 = mArchetypes[j];
275 }
276
277 if( mArchetypes.count() > 2 )
278 {
279 cycles = 0;
280 do
281 {
282 k = rand() % mArchetypes.count();
283 cur_sex_weight = *(mArchetypes[k]->mParamMap[ male_param_id ]);
284 cycles++;
285 } while(
286 (cycles < MAX_CYCLES) &&
287 ( (i == k) || (j == k) || (cur_sex_weight != sex_weight) )
288 );
289
290 if( cycles >= MAX_CYCLES )
291 {
292 return;
293 }
294
295 arch3 = mArchetypes[k];
296 }
297
298 // Lame generation of barycentric coordinates
299 F32 b1 = F32( rand() ) / RAND_MAX;
300 F32 b2 = (F32( rand() ) / RAND_MAX) * (1.f - b1);
301 F32 b3 = 1.f - b1 - b2;
302
303// ESex old_sex = avatar->getSex();
304
305 // Pull params
306 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
307 {
308 if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) )
309 {
310 S32 param_id = param->getID();
311
312 // don't try to blend male/female param...as fp innaccuracy will break the [0 | 1] semantics
313 if (param_id != male_param_id)
314 {
315
316 F32* weight1p = arch1->getParam( param_id );
317 F32 weight1 = weight1p ? *weight1p : param->getDefaultWeight();
318 F32 net_weight = weight1;
319
320 if( arch2 && arch3 )
321 {
322 F32* weight2p = arch2->getParam( param_id );
323 F32 weight2 = weight2p ? *weight2p : param->getDefaultWeight();
324
325 F32* weight3p = arch3->getParam( param_id );
326 F32 weight3 = weight3p ? *weight3p : param->getDefaultWeight();
327
328 net_weight = b1 * weight1 + b2 * weight2 + b3 * weight3;
329 }
330
331 param->setAnimationTarget(net_weight, TRUE);
332 }
333 }
334 }
335
336 // Find the archetype with the greatest influence
337 LLAppearance* dominant_arch = arch1;
338 if( (b2 > b1) && (b2 > b3) )
339 {
340 dominant_arch = arch2;
341 }
342 else
343 if( (b3 > b1) && (b3 > b2) )
344 {
345 dominant_arch = arch3;
346 }
347
348
349 // Pull Textures from the dominant archetype
350 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
351 {
352 if( LLVOAvatar::isTextureIndexBaked( te ) )
353 {
354 continue;
355 }
356
357 if( LLVOAvatar::getTEWearableType( te ) == type )
358 {
359 LLUUID image_id = dominant_arch->getTexture( te );
360 if( image_id.isNull() )
361 {
362 image_id = LLVOAvatar::getDefaultTEImageID( te );
363 }
364
365 LLViewerImage* image = gImageList.getImage( image_id );
366 if( image )
367 {
368 avatar->setLocTexTE( te, image, TRUE );
369 }
370 }
371 }
372
373// avatar->setVisualParamWeight( "male", sex_weight );
374
375 avatar->startAppearanceAnimation(TRUE, TRUE);
376 avatar->updateVisualParams();
377
378// ESex new_sex = avatar->getSex();
379// if( old_sex != new_sex )
380// {
381// avatar->updateSexDependentLayerSets( TRUE );
382// }
383
384 avatar->updateMeshTextures();
385 gAgent.sendAgentSetAppearance();
386}