1 #include "bodyarch.h"
2
BodyArch()3 BodyArch::BodyArch()
4 {
5 settings = Settings::Instance();
6 totalWeight = 0.0f;
7 bodypartspacer = 2.2f;
8 }
9
buildArch()10 void BodyArch::buildArch()
11 {
12 // string original;
13 // original.append("b 99999 box 0 75 75 200\n");
14 // original.append("b 99998 box 0 75 75 200\n");
15 // original.append("b 99997 box 0 75 75 200\n");
16 // original.append("m 99999 50, 50, 100\n");
17 // original.append("c 99999 99998 99999 1.5707 0 0 0 0 -0.25 -0.7853 99998 1.5707 0 0 0 0 0.25 0.7853\n");
18 // original.append("c 99997 99996 99998 1.5707 0 0 0 0 -0.25 -0.7853 99997 1.5707 0 0 0 0 0.25 0.7853\n");
19 // original.append("cm 99995 99994 99997 0 1.5707 0 0 0 -0.15 -0.7853 99999 0 1.5707 0 0 0 0.25 0.7853\n");
20 // setArch(&original);
21
22 // string fourlegged;
23 // // body
24 // fourlegged.append("b 99999 box 0 200 100 400\n");
25 // // 4 long legs
26 // fourlegged.append("b 99998 box 0 150 40 40\n");
27 // fourlegged.append("b 99997 box 0 150 40 40\n");
28 // fourlegged.append("b 99996 box 0 150 40 40\n");
29 // fourlegged.append("b 99995 box 0 150 40 40\n");
30 // // mouth
31 // fourlegged.append("m 99999 50, 50, 100\n");
32 // // connections
33 // fourlegged.append("c 99999 99998 99999 0 0 0.7853 -0.2 0 -0.325 -0.7853 99998 0 0 0 0.25 0 0 0.7853\n");
34 // fourlegged.append("c 99997 99996 99999 0 0 0.7853 -0.2 0 0.325 -0.7853 99997 0 0 0 0.25 0 0 0.7853\n");
35 // fourlegged.append("c 99995 99994 99999 0 0 -0.7853 0.2 0 -0.325 -0.7853 99996 0 0 0 -0.25 0 0 0.7853\n");
36 // fourlegged.append("c 99993 99992 99999 0 0 -0.7853 0.2 0 0.325 -0.7853 99995 0 0 0 -0.25 0 0 0.7853\n");
37 // fourlegged.append("cm 99991 99990 99999 1.5707 0 0 0 0 -0.15 -0.3926 99999 1.5707 0 0 0 0 0.45 0.3926\n");
38 // setArch(&fourlegged);
39
40
41
42 // string original;
43 // original.append("b 1000 box 0 200 200 200\n");
44 // original.append("b 1001 box 0 100 100 100\n");
45 // original.append("b 1002 box 0 100 100 100\n");
46 // original.append("b 1003 box 0 100 100 100\n");
47 // original.append("b 1004 box 0 100 100 100\n");
48 // original.append("m 99999 50, 50, 100\n");
49 //
50 // -x
51 // original.append("c 1000 1001 1000 0.5707 1.3707 0.7707 -0.3 0 0 -0.7853 1001 1.1707 0.0707 0.5707 0.15 0 0 0.7853\n");
52 // -z
53 // original.append("c 1002 1003 1000 1.5707 1.5707 1.5707 0 0 -0.3 -0.7853 1002 1.5707 1.5707 1.5707 0 0 0.15 0.7853\n");
54 // +z
55 // original.append("c 1004 1005 1000 1.5707 0 0 0 0 0.3 -0.7853 1003 1.5707 0 0 0 0 -0.15 0.7853\n");
56 // +x
57 // original.append("c 1006 1007 1000 1.5707 0 0 0.3 0 0 -0.7853 1004 1.5707 0 0 -0.15 0 0 0.7853\n");
58 // setArch(&original);
59
60 // Create a central body
61 archBodyparts.push_back( archBodypart() );
62 archBodypart *bp = &archBodyparts[archBodyparts.size()-1];
63 bp->id = 1000;
64 bp->type = 0;
65 bp->materialID = 0;
66 bp->x = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") );
67 bp->y = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") );
68 bp->z = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") );
69
70 // add random more
71 unsigned int runs = randgen->Instance()->get( 0, settings->getCVar("body_maxbodypartsatbuildtime")-1 ); // -1 -> central bodypart
72 for ( unsigned int i=0; i < runs; i++ )
73 addRandomBodypart();
74
75 addRandomMouth();
76 }
77
removeBodypart(unsigned int id)78 void BodyArch::removeBodypart(unsigned int id)
79 {
80 // cerr << "requested removal of bodypart id " << id << endl;
81
82 // find constraints where this bodypart is id1, in order to remove connected bodyparts
83 for ( unsigned int i = 0; i < archConstraints.size(); i++ )
84 {
85 archConstraint* c = &archConstraints[i];
86 if ( c->id_1 == id )
87 {
88 // cerr << " is connected to " << c->isMouthConstraint << " " << c->id_2 << endl;
89 if ( c->isMouthConstraint )
90 removeMouth( findMouth(c->id_2) );
91 else
92 removeBodypart( c->id_2 );
93 }
94 }
95
96 // cerr << "really removing " << id << " which is " << findBodypart( id ) << endl;
97 archBodyparts.erase( archBodyparts.begin() + findBodypart(id) );
98 }
99
removeMouth(unsigned int id)100 void BodyArch::removeMouth(unsigned int id)
101 {
102 // cerr << "removing mouth " << id << endl;
103 archMouths.erase(archMouths.begin()+id);
104 }
105
addRandomMouth()106 void BodyArch::addRandomMouth()
107 {
108 // Throw in a mouth
109 archMouths.push_back( archMouth() );
110 archMouth* mo = &archMouths[archMouths.size()-1];
111 mo->id = 1000;
112 mo->x = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") );
113 mo->y = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") );
114 mo->z = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") );
115
116 // Get it connected somehow
117
118 unsigned int connID1 = randgen->Instance()->get( 0, archBodyparts.size()-1 );
119 unsigned int connID2 = archMouths.size()-1;
120
121 addRandomConstraint(connID1, connID2, true);
122 }
123
addRandomBodypart()124 void BodyArch::addRandomBodypart()
125 {
126 // Throw in a bodypart
127 archBodyparts.push_back( archBodypart() );
128 archBodypart *bp = &archBodyparts[archBodyparts.size()-1];
129 bp->id = 0; // to avoid uninitialized id
130 bp->id = getUniqueBodypartID();
131 bp->type = 0;
132 bp->materialID = 0;
133 bp->x = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") );
134 bp->y = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") );
135 bp->z = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") );
136
137 // Get it connected somehow
138 unsigned int connID1 = randgen->Instance()->get( 0, archBodyparts.size()-1 );
139 unsigned int connID2 = archBodyparts.size()-1;
140 while ( connID1 == connID2 )
141 connID1 = randgen->Instance()->get( 0, archBodyparts.size()-1 );
142
143 addRandomConstraint(connID1, connID2, false);
144 }
145
addRandomConstraint(unsigned int connID1,unsigned int connID2,bool isMouth)146 void BodyArch::addRandomConstraint(unsigned int connID1, unsigned int connID2, bool isMouth)
147 {
148 archConstraints.push_back( archConstraint() );
149 archConstraint *co = &archConstraints[archConstraints.size()-1];
150
151 co->isMouthConstraint = isMouth;
152 // first initialize constraint id's
153 co->constraint_id1 = 0;
154 co->constraint_id2 = 0;
155 co->constraint_id1 = getUniqueConstraintID();
156 co->constraint_id2 = getUniqueConstraintID();
157 co->id_1 = archBodyparts[ connID1 ].id;
158 if ( isMouth )
159 co->id_2 = archMouths[ connID2 ].id;
160 else
161 co->id_2 = archBodyparts[ connID2 ].id;
162
163 co->rot_x_1 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000;
164 co->rot_y_1 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000;
165 co->rot_z_1 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000;
166
167 co->rot_x_2 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000;
168 co->rot_y_2 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000;
169 co->rot_z_2 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000;
170
171 randomConstraintPosition(co, 1, connID1);
172 randomConstraintPosition(co, 2, connID2);
173
174 co->limit_1 = (float)randgen->Instance()->get( 0, 7853 ) / -10000;
175 co->limit_2 = -1.0f * co->limit_1;
176 }
177
randomConstraintPosition(archConstraint * co,unsigned int OneOrTwo,unsigned int connID)178 void BodyArch::randomConstraintPosition(archConstraint* co, unsigned int OneOrTwo, unsigned int connID)
179 {
180 if ( OneOrTwo == 1 )
181 {
182 co->XYZ = randgen->Instance()->get( 0, 2 );
183 co->sign = randgen->Instance()->get( 0, 1 );
184 if ( co->sign == 0 ) co->sign = -1;
185
186 // now we know the plane to connect to, determine positions
187 if ( co->XYZ == 0 ) // X
188 {
189 // ((x / 1000.0f) / 2) * 1.5f * co->sign =
190 co->pos_x_1 = (archBodyparts[connID].x / 2000.0f) * co->sign * bodypartspacer;
191 co->pos_y_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].y)*2) - archBodyparts[connID].y) / 1000;
192 co->pos_z_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].z)*2) - archBodyparts[connID].z) / 1000;
193 }
194 else if ( co->XYZ == 1 ) // Y
195 {
196 co->pos_x_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].x)*2) - archBodyparts[connID].x) / 1000;
197 co->pos_y_1 = (archBodyparts[connID].y / 2000.0f) * co->sign * bodypartspacer;
198 co->pos_z_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].z)*2) - archBodyparts[connID].z) / 1000;
199 }
200 else // Z
201 {
202 co->pos_x_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].x)*2) - archBodyparts[connID].x) / 1000;
203 co->pos_y_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].y)*2) - archBodyparts[connID].y) / 1000;
204 co->pos_z_1 = (archBodyparts[connID].z / 2000.0f) * co->sign * bodypartspacer;
205 }
206 }
207 else
208 {
209 int othersign = -1 * co->sign;
210 if ( !co->isMouthConstraint )
211 {
212 if ( co->XYZ == 0 ) // X
213 {
214 co->pos_x_2 = (archBodyparts[connID].x / 2000.0f) * othersign * bodypartspacer;
215 co->pos_y_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].y)*2) - archBodyparts[connID].y) / 1000;
216 co->pos_z_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].z)*2) - archBodyparts[connID].z) / 1000;
217 }
218 else if ( co->XYZ == 1 ) // Y
219 {
220 co->pos_x_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].x)*2) - archBodyparts[connID].x) / 1000;
221 co->pos_y_2 = (archBodyparts[connID].y / 2000.0f) * othersign * bodypartspacer;
222 co->pos_z_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].z)*2) - archBodyparts[connID].z) / 1000;
223 }
224 else // Z
225 {
226 co->pos_x_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].x)*2) - archBodyparts[connID].x) / 1000;
227 co->pos_y_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].y)*2) - archBodyparts[connID].y) / 1000;
228 co->pos_z_2 = (archBodyparts[connID].z / 2000.0f) * othersign * bodypartspacer;
229 }
230 }
231 else
232 {
233 if ( co->XYZ == 0 ) // X
234 {
235 co->pos_x_2 = (archMouths[connID].x / 2000.0f) * othersign * bodypartspacer;
236 co->pos_y_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].y)*2) - archMouths[connID].y) / 1000;
237 co->pos_z_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].z)*2) - archMouths[connID].z) / 1000;
238 }
239 else if ( co->XYZ == 1 ) // Y
240 {
241 co->pos_x_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].x)*2) - archMouths[connID].x) / 1000;
242 co->pos_y_2 = (archMouths[connID].y / 2000.0f) * othersign * bodypartspacer;
243 co->pos_z_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].z)*2) - archMouths[connID].z) / 1000;
244 }
245 else // Z
246 {
247 co->pos_x_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].x)*2) - archMouths[connID].x) / 1000;
248 co->pos_y_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].y)*2) - archMouths[connID].y) / 1000;
249 co->pos_z_2 = (archMouths[connID].z / 2000.0f) * othersign * bodypartspacer;
250 }
251 }
252 }
253 }
254
mutate(unsigned int runs)255 void BodyArch::mutate(unsigned int runs)
256 {
257 for ( unsigned int i=0; i < runs; i++ )
258 {
259 unsigned int tsum = settings->getCVar("body_percentmutateeffectchangecolor")
260 + settings->getCVar("body_percentmutateeffectchangecolor_slightly")
261 + settings->getCVar("body_percentmutateeffectaddbodypart")
262 + settings->getCVar("body_percentmutateeffectremovebodypart")
263 + settings->getCVar("body_percentmutateeffectresizebodypart")
264 + settings->getCVar("body_percentmutateeffectresizebodypart_slightly")
265 + settings->getCVar("body_percentmutateeffectresizehead")
266 + settings->getCVar("body_percentmutateeffectresizehead_slightly")
267 + settings->getCVar("body_percentmutateeffectchangeconstraintlimits")
268 + settings->getCVar("body_percentmutateeffectchangeconstraintlimits_slightly")
269 + settings->getCVar("body_percentmutateeffectchangeconstraintangles")
270 + settings->getCVar("body_percentmutateeffectchangeconstraintangles_slightly")
271 + settings->getCVar("body_percentmutateeffectchangeconstraintposition")
272 + settings->getCVar("body_percentmutateeffectchangeconstraintposition_slightly")
273 + settings->getCVar("body_percentmutateeffectrepositionhead")
274 ;
275
276 unsigned int mode = randgen->Instance()->get(1,tsum);
277
278 // CHANGE COLOR
279 unsigned int modesum = settings->getCVar("body_percentmutateeffectchangecolor");
280 if ( mode <= modesum )
281 {
282 // mutate color
283 unsigned int ncolor = randgen->Instance()->get(0,2);
284
285 if ( ncolor == 0 )
286 color.r = (float)RandGen::Instance()->get(0,100)/100.0f;
287 else if ( ncolor == 1 )
288 color.g = (float)RandGen::Instance()->get(0,100)/100.0f;
289 else if ( ncolor == 2 )
290 color.b = (float)RandGen::Instance()->get(0,100)/100.0f;
291
292 continue;
293 }
294
295 // CHANGE COLOR SLIGHTLY
296 modesum += settings->getCVar("body_percentmutateeffectchangecolor_slightly");
297 if ( mode <= modesum )
298 {
299 // mutate color
300 unsigned int ncolor = randgen->Instance()->get(0,2);
301 unsigned int nweight = randgen->Instance()->get(1,10);
302 float amount = 0.01 * nweight;
303
304 if ( randgen->Instance()->get(0,1) == 0 )
305 amount *= -1;
306
307 if ( ncolor == 0 )
308 color.r += amount;
309 else if ( ncolor == 1 )
310 color.g += amount;
311 else if ( ncolor == 2 )
312 color.b += amount;
313
314 if ( color.r < 0.1f )
315 {
316 float diff = 0.1f - color.r;
317 color.r += diff; color.g += diff; color.b += diff; color.a += diff;
318 }
319 if ( color.g < 0.1f )
320 {
321 float diff = 0.1f - color.g;
322 color.r += diff; color.g += diff; color.b += diff; color.a += diff;
323 }
324 if ( color.b < 0.1f )
325 {
326 float diff = 0.1f - color.b;
327 color.r += diff; color.g += diff; color.b += diff; color.a += diff;
328 }
329
330 if ( color.r > 1.0f && color.g > 1.0f && color.b > 1.0f )
331 color.normalize();
332
333 continue;
334 }
335
336 // ADD BODYPART
337 modesum += settings->getCVar("body_percentmutateeffectaddbodypart");
338 if ( mode <= modesum )
339 {
340 if ( archBodyparts.size() < settings->getCVar("body_maxbodyparts") )
341 {
342 // cerr << "adding bodypart" << endl;
343 addRandomBodypart();
344 // cerr << "done adding bodypart" << endl;
345 }
346 else
347 runs++;
348 continue;
349 }
350
351 // REMOVE BODYPART
352 modesum += settings->getCVar("body_percentmutateeffectremovebodypart");
353 if ( mode <= modesum )
354 {
355 if ( archBodyparts.size() > 2 )
356 {
357 // pick a random bodypart
358 unsigned int bid = randgen->Instance()->get( 0, archBodyparts.size()-1 );
359
360 // if not main body, remove it
361 if ( archBodyparts[bid].id != 1000 )
362 {
363 // cerr << "removing bodypart " << bid << " id " << archBodyparts[bid].id << endl;
364
365 removeBodypart( archBodyparts[bid].id );
366
367 // cerr << "removing obsolete constraints, expected errors:" << endl;
368 for ( int i = 0; i < (int)archConstraints.size(); i++ )
369 {
370 archConstraint* c = &archConstraints[i];
371 if ( findBodypart( c->id_1 ) == -1 )
372 {
373 archConstraints.erase(archConstraints.begin()+i);
374 i--;
375 }
376 else if ( c->isMouthConstraint && findMouth( c->id_2 ) == -1 )
377 {
378 archConstraints.erase(archConstraints.begin()+i);
379 i--;
380 }
381 else if ( !c->isMouthConstraint && findBodypart( c->id_2 ) == -1 )
382 {
383 archConstraints.erase(archConstraints.begin()+i);
384 i--;
385 }
386 }
387 // cerr << "done removing obsolete constraints" << endl << endl;
388
389 // cerr << "done removing bodypart" << endl;
390
391 // re add mouth if needed
392 if ( archMouths.size() == 0 )
393 addRandomMouth();
394 }
395 else
396 runs++;
397
398 }
399 else
400 runs++;
401 continue;
402 }
403
404 // RESIZE BODYPART
405 modesum += settings->getCVar("body_percentmutateeffectresizebodypart");
406 if ( mode <= modesum )
407 {
408 // cerr << "resize bodypart" << endl;
409
410 // pick a random bodypart
411 unsigned int bid = randgen->Instance()->get( 0, archBodyparts.size()-1 );
412 archBodypart *bp = &archBodyparts[bid];
413
414 unsigned int axismode = randgen->Instance()->get(0,2);
415 if ( axismode == 0 )
416 bp->x = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") );
417 else if ( axismode == 1 )
418 bp->y = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") );
419 else
420 bp->z = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") );
421
422 // reposition the constraints back to the resized bodypart
423 repositiontoConstraints(bp);
424
425 // cerr << "done resize bodypart" << endl;
426 continue;
427 }
428
429 // RESIZE BODYPART SLIGHTLY
430 modesum += settings->getCVar("body_percentmutateeffectresizebodypart_slightly");
431 if ( mode <= modesum )
432 {
433 // cerr << "resize bodypart slightly" << endl;
434
435 // pick a random bodypart
436 unsigned int bid = randgen->Instance()->get( 0, archBodyparts.size()-1 );
437 archBodypart* bp = &archBodyparts[bid];
438
439 unsigned int axismode = randgen->Instance()->get(0,2);
440 unsigned int direction = randgen->Instance()->get(0,1);
441 if ( axismode == 0 )
442 {
443 if ( direction == 0 )
444 bp->x += randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 );
445 else
446 bp->x -= randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 );
447 }
448 else if ( axismode == 1 )
449 {
450 if ( direction == 0 )
451 bp->y += randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 );
452 else
453 bp->y -= randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 );
454 }
455 else
456 {
457 if ( direction == 0 )
458 bp->z += randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 );
459 else
460 bp->z -= randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 );
461 }
462
463 // see that they didn't go over their limits
464 if ( bp->x < settings->getCVar("body_minbodypartsize") )
465 bp->x = settings->getCVar("body_minbodypartsize");
466 else if ( bp->x > settings->getCVar("body_maxbodypartsize") )
467 bp->x = settings->getCVar("body_minbodypartsize");
468
469 if ( bp->y < settings->getCVar("body_minbodypartsize") )
470 bp->y = settings->getCVar("body_minbodypartsize");
471 else if ( bp->y > settings->getCVar("body_maxbodypartsize") )
472 bp->y = settings->getCVar("body_minbodypartsize");
473
474 if ( bp->z < settings->getCVar("body_minbodypartsize") )
475 bp->z = settings->getCVar("body_minbodypartsize");
476 else if ( bp->z > settings->getCVar("body_maxbodypartsize") )
477 bp->z = settings->getCVar("body_minbodypartsize");
478
479 // reposition the constraints back to the resized bodypart
480 repositiontoConstraints(bp);
481
482 // cerr << "done resize bodypart" << endl;
483 continue;
484 }
485
486 // RESIZE HEAD
487 modesum += settings->getCVar("body_percentmutateeffectresizehead");
488 if ( mode <= modesum )
489 {
490 // cerr << "resize mouth" << endl;
491
492 // pick a random head
493 unsigned int mid = randgen->Instance()->get( 0, archMouths.size()-1 );
494 archMouth* head = &archMouths[mid];
495
496 unsigned int axismode = randgen->Instance()->get(0,2);
497 if ( axismode == 0 )
498 head->x = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") );
499 else if ( axismode == 1 )
500 head->y = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") );
501 else
502 head->z = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") );
503
504 // reposition the constraints back to the resized bodypart
505 repositiontoConstraints(head);
506
507 // cerr << "done resize head" << endl;
508 continue;
509 }
510
511 // RESIZE HEAD SLIGHTLY
512 modesum += settings->getCVar("body_percentmutateeffectresizehead_slightly");
513 if ( mode <= modesum )
514 {
515 // cerr << "resize head slightly" << endl;
516
517 // pick a random head
518 unsigned int mid = randgen->Instance()->get( 0, archMouths.size()-1 );
519 archMouth* head = &archMouths[mid];
520
521 unsigned int axismode = randgen->Instance()->get(0,2);
522 unsigned int direction = randgen->Instance()->get(0,1);
523 if ( axismode == 0 )
524 {
525 if ( direction == 0 )
526 head->x += randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 );
527 else
528 head->x -= randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 );
529 }
530 else if ( axismode == 1 )
531 {
532 if ( direction == 0 )
533 head->y += randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 );
534 else
535 head->y -= randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 );
536 }
537 else
538 {
539 if ( direction == 0 )
540 head->z += randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 );
541 else
542 head->z -= randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 );
543 }
544
545 // see that they didn't go over their limits
546 if ( head->x < settings->getCVar("body_minheadsize") )
547 head->x = settings->getCVar("body_minheadsize");
548 else if ( head->x > settings->getCVar("body_maxheadsize") )
549 head->x = settings->getCVar("body_minheadsize");
550
551 if ( head->y < settings->getCVar("body_minheadsize") )
552 head->y = settings->getCVar("body_minheadsize");
553 else if ( head->y > settings->getCVar("body_maxheadsize") )
554 head->y = settings->getCVar("body_minheadsize");
555
556 if ( head->z < settings->getCVar("body_minheadsize") )
557 head->z = settings->getCVar("body_minheadsize");
558 else if ( head->z > settings->getCVar("body_maxheadsize") )
559 head->z = settings->getCVar("body_minheadsize");
560
561 // reposition the constraints back to the resized bodypart
562 repositiontoConstraints(head);
563
564 // cerr << "done resize head" << endl;
565 continue;
566 }
567
568 // CHANGE CONSTRAINT LIMITS
569 modesum += settings->getCVar("body_percentmutateeffectchangeconstraintlimits");
570 if ( mode <= modesum )
571 {
572 // cerr << "changing constraint limits" << endl;
573
574 unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 );
575 archConstraint* co = &archConstraints[cid];
576 co->limit_1 = (float)randgen->Instance()->get( 0, 7853 ) / -10000;
577 co->limit_2 = -1.0f * co->limit_1;
578
579 // cerr << "done changing constraint limits" << endl;
580 continue;
581 }
582
583 // CHANGE CONSTRAINT LIMITS SLIGHTLY
584 modesum += settings->getCVar("body_percentmutateeffectchangeconstraintlimits_slightly");
585 if ( mode <= modesum )
586 {
587 // cerr << "changing constraint limits" << endl;
588
589 unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 );
590 archConstraint* co = &archConstraints[cid];
591
592 unsigned int direction = randgen->Instance()->get(0,1);
593
594 if ( direction == 0 )
595 co->limit_1 += 0.01f;
596 else
597 co->limit_1 -= 0.01f;
598 // check limits limits, ya
599 if ( co->limit_1 > 0.0f )
600 co->limit_1 = 0.0f;
601 if ( co->limit_1 < -0.7853f )
602 co->limit_1 = -0.7853f;
603
604 co->limit_2 = -1.0f * co->limit_1;
605
606 // cerr << "done changing constraint limits" << endl;
607 continue;
608 }
609 // CHANGE CONSTRAINT ANGLES
610 modesum += settings->getCVar("body_percentmutateeffectchangeconstraintangles");
611 if ( mode <= modesum )
612 {
613 // cerr << "changing constraint angles" << endl;
614
615 unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 );
616 archConstraint* co = &archConstraints[cid];
617 co->rot_x_1 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000;
618 co->rot_z_1 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000;
619 co->rot_y_1 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000;
620
621 co->rot_x_2 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000;
622 co->rot_y_2 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000;
623 co->rot_z_2 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000;
624
625 // cerr << "done changing constraint angles" << endl;
626 continue;
627 }
628
629 // CHANGE CONSTRAINT ANGLES SLIGHTLY
630 modesum += settings->getCVar("body_percentmutateeffectchangeconstraintangles_slightly");
631 if ( mode <= modesum )
632 {
633 // cerr << "changing constraint angles" << endl;
634
635 unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 );
636 archConstraint* co = &archConstraints[cid];
637
638 unsigned int XYZ = randgen->Instance()->get(0,2);
639 unsigned int direction = randgen->Instance()->get(0,1);
640 if ( direction == 0 )
641 {
642 if ( XYZ == 0 )
643 co->rot_x_1 += 0.01f;
644 else if ( XYZ == 1 )
645 co->rot_y_1 += 0.01f;
646 else
647 co->rot_z_1 += 0.01f;
648 }
649 else
650 {
651 if ( XYZ == 0 )
652 co->rot_x_1 -= 0.01f;
653 else if ( XYZ == 1 )
654 co->rot_y_1 -= 0.01f;
655 else
656 co->rot_z_1 -= 0.01f;
657 }
658
659 XYZ = randgen->Instance()->get(0,2);
660 direction = randgen->Instance()->get(0,1);
661 if ( direction == 0 )
662 {
663 if ( XYZ == 0 )
664 co->rot_x_2 += 0.01f;
665 else if ( XYZ == 1 )
666 co->rot_y_2 += 0.01f;
667 else
668 co->rot_z_2 += 0.01f;
669 }
670 else
671 {
672 if ( XYZ == 0 )
673 co->rot_x_2 -= 0.01f;
674 else if ( XYZ == 1 )
675 co->rot_y_2 -= 0.01f;
676 else
677 co->rot_z_2 -= 0.01f;
678 }
679
680 if ( co->rot_x_1 < -0.1571f )
681 co->rot_x_1 = -0.1571f;
682 if ( co->rot_x_1 > 0.1571f )
683 co->rot_x_1 = 0.1571f;
684 if ( co->rot_y_1 < -0.1571f )
685 co->rot_y_1 = -0.1571f;
686 if ( co->rot_y_1 > 0.1571f )
687 co->rot_y_1 = 0.1571f;
688 if ( co->rot_z_1 < -0.1571f )
689 co->rot_z_1 = -0.1571f;
690 if ( co->rot_z_1 > 0.1571f )
691 co->rot_z_1 = 0.1571f;
692
693 if ( co->rot_x_2 < -0.1571f )
694 co->rot_x_2 = -0.1571f;
695 if ( co->rot_x_2 > 0.1571f )
696 co->rot_x_2 = 0.1571f;
697 if ( co->rot_y_2 < -0.1571f )
698 co->rot_y_2 = -0.1571f;
699 if ( co->rot_y_2 > 0.1571f )
700 co->rot_y_2 = 0.1571f;
701 if ( co->rot_z_2 < -0.1571f )
702 co->rot_z_2 = -0.1571f;
703 if ( co->rot_z_2 > 0.1571f )
704 co->rot_z_2 = 0.1571f;
705
706 // cerr << "done changing constraint angles" << endl;
707 continue;
708 }
709
710 // REPOSITION A CONSTRAINT
711 modesum += settings->getCVar("body_percentmutateeffectchangeconstraintposition");
712 if ( mode <= modesum )
713 {
714 // cerr << "changing constraint position" << endl;
715
716 unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 );
717 archConstraint* co = &archConstraints[cid];
718
719 int connID1 = findBodypart(co->id_1);
720 int connID2;
721
722 if ( co->isMouthConstraint )
723 connID2 = findMouth(co->id_2);
724 else
725 connID2 = findBodypart(co->id_2);
726
727 // pick one of 2 bodies to reconnect
728 unsigned int body1or2 = randgen->Instance()->get( 1, 2 );
729
730 if ( body1or2 == 1 )
731 randomConstraintPosition(co, 1, connID1);
732 else
733 randomConstraintPosition(co, 2, connID2);
734
735 // cerr << "done changing constraint position" << endl;
736 continue;
737 }
738
739 // REPOSITION A CONSTRAINT SLIGHTLY
740 modesum += settings->getCVar("body_percentmutateeffectchangeconstraintposition_slightly");
741 if ( mode <= modesum )
742 {
743 // cerr << "changing constraint position" << endl;
744
745 unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 );
746 archConstraint* co = &archConstraints[cid];
747
748 int connID1 = findBodypart(co->id_1);
749 int connID2;
750
751 if ( co->isMouthConstraint )
752 connID2 = findMouth(co->id_2);
753 else
754 connID2 = findBodypart(co->id_2);
755
756 // pick one of 2 bodies to reconnect
757 unsigned int body1or2 = randgen->Instance()->get( 1, 2 );
758 unsigned int direction = randgen->Instance()->get( 0, 1 );
759 unsigned int axis1or2 = randgen->Instance()->get( 0, 1 );
760
761 if ( body1or2 == 1 ) {
762 // now we know the plane to connect to, determine positions
763 if ( co->XYZ == 0 ) { // X
764 if ( direction == 0 ) {
765 if ( axis1or2 == 0 ) co->pos_y_1 += archBodyparts[connID1].y / 100000;
766 else co->pos_z_1 += archBodyparts[connID1].z / 100000;
767 } else {
768 if ( axis1or2 == 0 ) co->pos_y_1 -= archBodyparts[connID1].y / 100000;
769 else co->pos_z_1 -= archBodyparts[connID1].z / 100000;
770 }
771 }
772 else if ( co->XYZ == 1 ) { // Y
773 if ( direction == 0 ) {
774 if ( axis1or2 == 0 ) co->pos_x_1 += archBodyparts[connID1].x / 100000;
775 else co->pos_z_1 += archBodyparts[connID1].z / 100000;
776 } else {
777 if ( axis1or2 == 0 ) co->pos_x_1 -= archBodyparts[connID1].x / 100000;
778 else co->pos_z_1 -= archBodyparts[connID1].z / 100000;
779 }
780 }
781 else { // Z
782 if ( direction == 0 ) {
783 if ( axis1or2 == 0 ) co->pos_x_1 += archBodyparts[connID1].x / 100000;
784 else co->pos_y_1 += archBodyparts[connID1].y / 100000;
785 } else {
786 if ( axis1or2 == 0 ) co->pos_x_1 -= archBodyparts[connID1].x / 100000;
787 else co->pos_y_1 -= archBodyparts[connID1].y / 100000;
788 }
789 }
790 if ( co->pos_x_1 < archBodyparts[connID1].x/-2000 )
791 co->pos_x_1 = archBodyparts[connID1].x/-2000;
792 if ( co->pos_x_1 > archBodyparts[connID1].x/2000 )
793 co->pos_x_1 = archBodyparts[connID1].x/2000;
794 if ( co->pos_y_1 < archBodyparts[connID1].y/-2000 )
795 co->pos_y_1 = archBodyparts[connID1].y/-2000;
796 if ( co->pos_y_1 > archBodyparts[connID1].y/2000 )
797 co->pos_y_1 = archBodyparts[connID1].y/2000;
798 if ( co->pos_z_1 < archBodyparts[connID1].z/-2000 )
799 co->pos_z_1 = archBodyparts[connID1].z/-2000;
800 if ( co->pos_z_1 > archBodyparts[connID1].z/2000 )
801 co->pos_z_1 = archBodyparts[connID1].z/2000;
802 }
803 else {
804 if ( !co->isMouthConstraint ) {
805 // now we know the plane to connect to, determine positions
806 if ( co->XYZ == 0 ) { // X
807 if ( direction == 0 ) {
808 if ( axis1or2 == 0 ) co->pos_y_2 += archBodyparts[connID2].y / 100000;
809 else co->pos_z_2 += archBodyparts[connID2].z / 100000;
810 } else {
811 if ( axis1or2 == 0 ) co->pos_y_2 -= archBodyparts[connID2].y / 100000;
812 else co->pos_z_2 -= archBodyparts[connID2].z / 100000;
813 }
814 }
815 else if ( co->XYZ == 1 ) { // Y
816 if ( direction == 0 ) {
817 if ( axis1or2 == 0 ) co->pos_x_2 += archBodyparts[connID2].x / 100000;
818 else co->pos_z_2 += archBodyparts[connID2].z / 100000;
819 } else {
820 if ( axis1or2 == 0 ) co->pos_x_2 -= archBodyparts[connID2].x / 100000;
821 else co->pos_z_2 -= archBodyparts[connID2].z / 100000;
822 }
823 }
824 else { // Z
825 if ( direction == 0 ) {
826 if ( axis1or2 == 0 ) co->pos_x_2 += archBodyparts[connID2].x / 100000;
827 else co->pos_y_2 += archBodyparts[connID2].y / 100000;
828 } else {
829 if ( axis1or2 == 0 ) co->pos_x_2 -= archBodyparts[connID2].x / 100000;
830 else co->pos_y_2 -= archBodyparts[connID2].y / 100000;
831 }
832 }
833 if ( co->pos_x_2 < archBodyparts[connID2].x/-2000 )
834 co->pos_x_2 = archBodyparts[connID2].x/-2000;
835 if ( co->pos_x_2 > archBodyparts[connID2].x/2000 )
836 co->pos_x_2 = archBodyparts[connID2].x/2000;
837 if ( co->pos_y_2 < archBodyparts[connID2].y/-2000 )
838 co->pos_y_2 = archBodyparts[connID2].y/-2000;
839 if ( co->pos_y_2 > archBodyparts[connID2].y/2000 )
840 co->pos_y_2 = archBodyparts[connID2].y/2000;
841 if ( co->pos_z_2 < archBodyparts[connID2].z/-2000 )
842 co->pos_z_2 = archBodyparts[connID2].z/-2000;
843 if ( co->pos_z_2 > archBodyparts[connID2].z/2000 )
844 co->pos_z_2 = archBodyparts[connID2].z/2000;
845 }
846 else {
847 if ( co->XYZ == 0 ) { // X
848 if ( direction == 0 ) {
849 if ( axis1or2 == 0 ) co->pos_y_2 += archMouths[connID2].y / 100000;
850 else co->pos_z_2 += archMouths[connID2].z / 100000;
851 } else {
852 if ( axis1or2 == 0 ) co->pos_y_2 -= archMouths[connID2].y / 100000;
853 else co->pos_z_2 -= archMouths[connID2].z / 100000;
854 }
855 }
856 else if ( co->XYZ == 1 ) { // Y
857 if ( direction == 0 ) {
858 if ( axis1or2 == 0 ) co->pos_x_2 += archMouths[connID2].x / 100000;
859 else co->pos_z_2 += archMouths[connID2].z / 100000;
860 } else {
861 if ( axis1or2 == 0 ) co->pos_x_2 -= archMouths[connID2].x / 100000;
862 else co->pos_z_2 -= archMouths[connID2].z / 100000;
863 }
864 }
865 else { // Z
866 if ( direction == 0 ) {
867 if ( axis1or2 == 0 ) co->pos_x_2 += archMouths[connID2].x / 100000;
868 else co->pos_y_2 += archMouths[connID2].y / 100000;
869 } else {
870 if ( axis1or2 == 0 ) co->pos_x_2 -= archMouths[connID2].x / 100000;
871 else co->pos_y_2 -= archMouths[connID2].y / 100000;
872 }
873 }
874 if ( co->pos_x_2 < archMouths[connID2].x/-2000 )
875 co->pos_x_2 = archMouths[connID2].x/-2000;
876 if ( co->pos_x_2 > archMouths[connID2].x/2000 )
877 co->pos_x_2 = archMouths[connID2].x/2000;
878 if ( co->pos_y_2 < archMouths[connID2].y/-2000 )
879 co->pos_y_2 = archMouths[connID2].y/-2000;
880 if ( co->pos_y_2 > archMouths[connID2].y/2000 )
881 co->pos_y_2 = archMouths[connID2].y/2000;
882 if ( co->pos_z_2 < archMouths[connID2].z/-2000 )
883 co->pos_z_2 = archMouths[connID2].z/-2000;
884 if ( co->pos_z_2 > archMouths[connID2].z/2000 )
885 co->pos_z_2 = archMouths[connID2].z/2000;
886 }
887 }
888
889 // randomConstraintPosition(co, 2, connID2);
890
891 // cerr << "done changing constraint position" << endl;
892 continue;
893 }
894
895 // REMOVE AND ADD MOUTH
896 modesum += settings->getCVar("body_percentmutateeffectrepositionhead");
897 if ( mode <= modesum )
898 {
899 // cerr << "remove and add mouth" << endl;
900
901 for ( int i = 0; i < (int)archConstraints.size(); i++ )
902 {
903 archConstraint* c = &archConstraints[i];
904 if ( c->isMouthConstraint && c->id_2 == archMouths[0].id )
905 {
906 archConstraints.erase(archConstraints.begin()+i);
907 i--;
908 }
909 }
910
911 removeMouth(0);
912
913 addRandomMouth();
914
915 // cerr << "done remove and add mouth" << endl;
916 continue;
917 }
918
919 // if we reach here, none were processed, decrease runs by 1 to make sure we get a hit
920 if ( modesum > 0 )
921 runs++;
922 }
923 }
924
repositiontoConstraints(archBodypart * bp)925 void BodyArch::repositiontoConstraints( archBodypart* bp )
926 {
927 // reposition the constraints back to the resized bodypart / mouth
928 for ( int i = 0; i < (int)archConstraints.size(); i++ )
929 {
930 archConstraint* co = &archConstraints[i];
931 if ( findBodypart( co->id_1 ) == (int)bp->id )
932 {
933 if ( co->XYZ == 0 ) // X
934 co->pos_x_1 = (bp->x / 2000.0f) * co->sign * bodypartspacer;
935 else if ( co->XYZ == 1 ) // Y
936 co->pos_y_1 = (bp->y / 2000.0f) * co->sign * bodypartspacer;
937 else if ( co->XYZ == 2 ) // Z
938 co->pos_z_1 = (bp->z / 2000.0f) * co->sign * bodypartspacer;
939 }
940 else if ( !co->isMouthConstraint && findBodypart( co->id_2 ) == (int)bp->id )
941 {
942 int othersign = -1 * co->sign;
943 if ( co->XYZ == 0 ) // X
944 co->pos_x_2 = (bp->x / 2000.0f) * othersign * bodypartspacer;
945 else if ( co->XYZ == 1 ) // Y
946 co->pos_y_2 = (bp->y / 2000.0f) * othersign * bodypartspacer;
947 else if ( co->XYZ == 2 ) // Z
948 co->pos_z_2 = (bp->z / 2000.0f) * othersign * bodypartspacer;
949 }
950 }
951 }
952
repositiontoConstraints(archMouth * bp)953 void BodyArch::repositiontoConstraints( archMouth* bp )
954 {
955 // reposition the constraints back to the resized bodypart / mouth
956 for ( int i = 0; i < (int)archConstraints.size(); i++ )
957 {
958 archConstraint* co = &archConstraints[i];
959 if ( co->isMouthConstraint && findBodypart( co->id_2 ) == (int)bp->id )
960 {
961 int othersign = -1 * co->sign;
962 if ( co->XYZ == 0 ) // X
963 co->pos_x_2 = (bp->x / 2000.0f) * othersign * bodypartspacer;
964 else if ( co->XYZ == 1 ) // Y
965 co->pos_y_2 = (bp->y / 2000.0f) * othersign * bodypartspacer;
966 else if ( co->XYZ == 2 ) // Z
967 co->pos_z_2 = (bp->z / 2000.0f) * othersign * bodypartspacer;
968 }
969 }
970 }
971
findBodypart(unsigned int id)972 int BodyArch::findBodypart( unsigned int id )
973 {
974 for ( unsigned int i=0; i < archBodyparts.size(); i++ )
975 {
976 if ( archBodyparts[i].id == id )
977 {
978 return i;
979 }
980 }
981 // cerr << " NOT GOOD: cannot find a bodypart for the id " << id << endl;
982 return -1;
983 }
984
findMouth(unsigned int id)985 int BodyArch::findMouth( unsigned int id )
986 {
987 for ( unsigned int i=0; i < archMouths.size(); i++ )
988 {
989 if ( archMouths[i].id == id )
990 {
991 return i;
992 }
993 }
994 // cerr << " NOT GOOD " << endl;
995 // cerr << " NOT GOOD: cannot find a mouth for the id " << id << endl;
996 return -1;
997 }
998
getUniqueBodypartID()999 unsigned int BodyArch::getUniqueBodypartID()
1000 {
1001 unsigned int id = 1000;
1002 bool found = true;
1003 while ( found )
1004 {
1005 found = false;
1006 for ( unsigned int i = 0; i < archBodyparts.size() && !found; i++ )
1007 if ( archBodyparts[i].id == id )
1008 {
1009 found = true;
1010 id++;
1011 }
1012 }
1013 return id;
1014 }
1015
getUniqueConstraintID()1016 unsigned int BodyArch::getUniqueConstraintID()
1017 {
1018 unsigned int id = 1000;
1019 bool found = true;
1020 while ( found )
1021 {
1022 found = false;
1023 for ( unsigned int i = 0; i < archConstraints.size() && !found; i++ )
1024 {
1025 if ( archConstraints[i].constraint_id1 == id || archConstraints[i].constraint_id2 == id )
1026 {
1027 found = true;
1028 id++;
1029 }
1030 }
1031 }
1032 return id;
1033 }
1034
copyFrom(const BodyArch * otherBody)1035 void BodyArch::copyFrom(const BodyArch* otherBody)
1036 {
1037 color = otherBody->color;
1038 retinasize = otherBody->retinasize;
1039
1040 for ( unsigned int i=0; i < otherBody->archBodyparts.size(); i++ )
1041 {
1042 const archBodypart *obp = &otherBody->archBodyparts[i];
1043 archBodyparts.push_back( archBodypart() );
1044 archBodypart *bp = &archBodyparts[archBodyparts.size()-1];
1045
1046 bp->id = obp->id;
1047 bp->type = obp->type;
1048 bp->materialID = obp->materialID;
1049 bp->x = obp->x;
1050 bp->y = obp->y;
1051 bp->z = obp->z;
1052 }
1053
1054 for ( unsigned int i=0; i < otherBody->archMouths.size(); i++ )
1055 {
1056 const archMouth *omo = &otherBody->archMouths[i];
1057 archMouths.push_back( archMouth() );
1058 archMouth *mo = &archMouths[archMouths.size()-1];
1059
1060 mo->id = omo->id;
1061 mo->x = omo->x;
1062 mo->y = omo->y;
1063 mo->z = omo->z;
1064 }
1065
1066 for ( unsigned int i=0; i < otherBody->archConstraints.size(); i++ )
1067 {
1068 const archConstraint *oco = &otherBody->archConstraints[i];
1069 archConstraints.push_back( archConstraint() );
1070 archConstraint *co = &archConstraints[archConstraints.size()-1];
1071
1072 co->isMouthConstraint = oco->isMouthConstraint;
1073 co->constraint_id1 = oco->constraint_id1;
1074 co->constraint_id2 = oco->constraint_id2;
1075 co->XYZ = oco->XYZ;
1076 co->sign = oco->sign;
1077 co->id_1 = oco->id_1;
1078 co->id_2 = oco->id_2;
1079 co->rot_x_1 = oco->rot_x_1;
1080 co->rot_x_2 = oco->rot_x_2;
1081 co->rot_y_1 = oco->rot_y_1;
1082 co->rot_y_2 = oco->rot_y_2;
1083 co->rot_z_1 = oco->rot_z_1;
1084 co->rot_z_2 = oco->rot_z_2;
1085 co->pos_x_1 = oco->pos_x_1;
1086 co->pos_x_2 = oco->pos_x_2;
1087 co->pos_y_1 = oco->pos_y_1;
1088 co->pos_y_2 = oco->pos_y_2;
1089 co->pos_z_1 = oco->pos_z_1;
1090 co->pos_z_2 = oco->pos_z_2;
1091 co->limit_1 = oco->limit_1;
1092 co->limit_2 = oco->limit_2;
1093 }
1094 }
1095
setArch(string * content)1096 void BodyArch::setArch(string* content)
1097 {
1098 // cerr << *content << endl;
1099
1100 string contentCopy = *content;
1101 string line = parseH->Instance()->returnUntillStrip( "\n", contentCopy );
1102 while ( !line.empty() )
1103 {
1104 if ( Parser::Instance()->beginMatchesStrip( "color=", line ) )
1105 {
1106 string R = Parser::Instance()->returnUntillStrip( ",", line );
1107 string G = Parser::Instance()->returnUntillStrip( ",", line );
1108 string B = Parser::Instance()->returnUntillStrip( ";", line );
1109
1110 if(EOF == sscanf(R.c_str(), "%f", &color.r)) cerr << "ERROR INSERTING CRITTER (colorR)" << endl;
1111 if(EOF == sscanf(G.c_str(), "%f", &color.g)) cerr << "ERROR INSERTING CRITTER (colorG)" << endl;
1112 if(EOF == sscanf(B.c_str(), "%f", &color.b)) cerr << "ERROR INSERTING CRITTER (colorB)" << endl;
1113 color.a = 0.0f;
1114 }
1115 else if ( Parser::Instance()->beginMatchesStrip( "retinasize=", line ) )
1116 {
1117 string RES = Parser::Instance()->returnUntillStrip( ";", line );
1118 //cerr << "RES: " << RES << endl;
1119 if(EOF == sscanf(RES.c_str(), "%d", &retinasize)) cerr << "ERROR INSERTING CRITTER" << endl;
1120 }
1121 else if ( parseH->Instance()->beginMatchesStrip( "b ", line ) )
1122 {
1123 // b 99999 box 0 75 75 200
1124
1125 // cerr << "bodypart" << endl;
1126
1127 archBodyparts.push_back( archBodypart() );
1128 archBodypart *bp = &archBodyparts[archBodyparts.size()-1];
1129
1130 string bodypartID = Parser::Instance()->returnUntillStrip( " ", line );
1131 if(EOF == sscanf(bodypartID.c_str(), "%d", &bp->id)) cerr << "error in parsing body" << endl;
1132 string bodypartShape = Parser::Instance()->returnUntillStrip( " ", line );
1133 if ( bodypartShape == "box" )
1134 {
1135 // type = box
1136 bp->type = 0;
1137
1138 // materialID
1139 string materialID = Parser::Instance()->returnUntillStrip( " ", line );
1140 if(EOF == sscanf(materialID.c_str(), "%d", &bp->materialID)) cerr << "error in parsing body" << endl;
1141
1142 // dimesions X Y Z
1143 string X = Parser::Instance()->returnUntillStrip( " ", line );
1144 string Y = Parser::Instance()->returnUntillStrip( " ", line );
1145 string Z = line;
1146 if(EOF == sscanf(X.c_str(), "%f", &bp->x)) cerr << "error in parsing body" << endl;
1147 if(EOF == sscanf(Y.c_str(), "%f", &bp->y)) cerr << "error in parsing body" << endl;
1148 if(EOF == sscanf(Z.c_str(), "%f", &bp->z)) cerr << "error in parsing body" << endl;
1149
1150
1151 /* cerr << endl << " id " << bp->id << endl;
1152 cerr << " type " << bp->type << endl;
1153 cerr << " material " << bp->materialID << endl;
1154 cerr << " x " << bp->x << endl;
1155 cerr << " y " << bp->y << endl;
1156 cerr << " z " << bp->z << endl;*/
1157 }
1158 }
1159 else if ( parseH->Instance()->beginMatchesStrip( "c ", line ) )
1160 {
1161 // c 99999 1.5707963 0 0 0 0 -0.25 99998 1.5707963 0 0 0 0 0.25
1162 // cm 0 1 1000 1001 1000 1.115 -0.752 -0.102 0.258 0.089 -0.133 -0.1103 1000 -1.4 -1.007 -1.287 -0.258 0.039 0.137 0.1103
1163 // cerr << "constraint" << endl;
1164
1165 archConstraint CO;
1166 archConstraints.push_back( CO );
1167 archConstraint *co = &archConstraints[archConstraints.size()-1];
1168
1169 // XYZ & sign
1170 string XYZ = Parser::Instance()->returnUntillStrip( " ", line );
1171 if(EOF == sscanf(XYZ.c_str(), "%d", &co->XYZ)) cerr << "error in parsing body" << endl;
1172 string SIGN = Parser::Instance()->returnUntillStrip( " ", line );
1173 if(EOF == sscanf(SIGN.c_str(), "%d", &co->sign)) cerr << "error in parsing body" << endl;
1174
1175 // CONSTRAINT IDS
1176 string ID = Parser::Instance()->returnUntillStrip( " ", line );
1177 if(EOF == sscanf(ID.c_str(), "%d", &co->constraint_id1)) cerr << "error in parsing body" << endl;
1178 ID = Parser::Instance()->returnUntillStrip( " ", line );
1179 if(EOF == sscanf(ID.c_str(), "%d", &co->constraint_id2)) cerr << "error in parsing body" << endl;
1180
1181 // CONNECTION TO BODYPART 1
1182 string ID_1 = Parser::Instance()->returnUntillStrip( " ", line );
1183 if(EOF == sscanf(ID_1.c_str(), "%d", &co->id_1)) cerr << "error in parsing body" << endl;
1184
1185 // ROTATION
1186 string ROT_X_1 = Parser::Instance()->returnUntillStrip( " ", line );
1187 if(EOF == sscanf(ROT_X_1.c_str(), "%f", &co->rot_x_1)) cerr << "error in parsing body" << endl;
1188 string ROT_Y_1 = Parser::Instance()->returnUntillStrip( " ", line );
1189 if(EOF == sscanf(ROT_Y_1.c_str(), "%f", &co->rot_y_1)) cerr << "error in parsing body" << endl;
1190 string ROT_Z_1 = Parser::Instance()->returnUntillStrip( " ", line );
1191 if(EOF == sscanf(ROT_Z_1.c_str(), "%f", &co->rot_z_1)) cerr << "error in parsing body" << endl;
1192
1193 // POSITION
1194 string POS_X_1 = Parser::Instance()->returnUntillStrip( " ", line );
1195 if(EOF == sscanf(POS_X_1.c_str(), "%f", &co->pos_x_1)) cerr << "error in parsing body" << endl;
1196 string POS_Y_1 = Parser::Instance()->returnUntillStrip( " ", line );
1197 if(EOF == sscanf(POS_Y_1.c_str(), "%f", &co->pos_y_1)) cerr << "error in parsing body" << endl;
1198 string POS_Z_1 = Parser::Instance()->returnUntillStrip( " ", line );
1199 if(EOF == sscanf(POS_Z_1.c_str(), "%f", &co->pos_z_1)) cerr << "error in parsing body" << endl;
1200
1201 // LIMIT
1202 string LIMIT_1 = Parser::Instance()->returnUntillStrip( " ", line );
1203 if(EOF == sscanf(LIMIT_1.c_str(), "%f", &co->limit_1)) cerr << "error in parsing body" << endl;
1204
1205 // CONNECTION TO BODYPART 2
1206 string ID_2 = Parser::Instance()->returnUntillStrip( " ", line );
1207 if(EOF == sscanf(ID_2.c_str(), "%d", &co->id_2)) cerr << "error in parsing body" << endl;
1208
1209 // ROTATION
1210 string ROT_X_2 = Parser::Instance()->returnUntillStrip( " ", line );
1211 if(EOF == sscanf(ROT_X_2.c_str(), "%f", &co->rot_x_2)) cerr << "error in parsing body" << endl;
1212 string ROT_Y_2 = Parser::Instance()->returnUntillStrip( " ", line );
1213 if(EOF == sscanf(ROT_Y_2.c_str(), "%f", &co->rot_y_2)) cerr << "error in parsing body" << endl;
1214 string ROT_Z_2 = Parser::Instance()->returnUntillStrip( " ", line );
1215 if(EOF == sscanf(ROT_Z_2.c_str(), "%f", &co->rot_z_2)) cerr << "error in parsing body" << endl;
1216
1217 // POSITION
1218 string POS_X_2 = Parser::Instance()->returnUntillStrip( " ", line );
1219 if(EOF == sscanf(POS_X_2.c_str(), "%f", &co->pos_x_2)) cerr << "error in parsing body" << endl;
1220 string POS_Y_2 = Parser::Instance()->returnUntillStrip( " ", line );
1221 if(EOF == sscanf(POS_Y_2.c_str(), "%f", &co->pos_y_2)) cerr << "error in parsing body" << endl;
1222 string POS_Z_2 = Parser::Instance()->returnUntillStrip( " ", line );
1223 if(EOF == sscanf(POS_Z_2.c_str(), "%f", &co->pos_z_2)) cerr << "error in parsing body" << endl;
1224
1225 // LIMIT
1226 string LIMIT_2 = line;
1227 if(EOF == sscanf(LIMIT_2.c_str(), "%f", &co->limit_2)) cerr << "error in parsing body" << endl;
1228 }
1229 else if ( parseH->Instance()->beginMatchesStrip( "cm ", line ) )
1230 {
1231 // cm 99999 1.5707963 0 0 0 0 -0.25 99998 1.5707963 0 0 0 0 0.25
1232
1233 // cerr << "constraint" << endl;
1234
1235 archConstraint CO;
1236 archConstraints.push_back( CO );
1237 archConstraint *co = &archConstraints[archConstraints.size()-1];
1238
1239 co->isMouthConstraint = true;
1240
1241 // XYZ & sign
1242 string XYZ = Parser::Instance()->returnUntillStrip( " ", line );
1243 if(EOF == sscanf(XYZ.c_str(), "%d", &co->XYZ)) cerr << "error in parsing body" << endl;
1244 string SIGN = Parser::Instance()->returnUntillStrip( " ", line );
1245 if(EOF == sscanf(SIGN.c_str(), "%d", &co->sign)) cerr << "error in parsing body" << endl;
1246
1247 // CONSTRAINT IDS
1248 string ID = Parser::Instance()->returnUntillStrip( " ", line );
1249 if(EOF == sscanf(ID.c_str(), "%d", &co->constraint_id1)) cerr << "error in parsing body" << endl;
1250 ID = Parser::Instance()->returnUntillStrip( " ", line );
1251 if(EOF == sscanf(ID.c_str(), "%d", &co->constraint_id2)) cerr << "error in parsing body" << endl;
1252
1253 // CONNECTION TO BODYPART 1
1254 string ID_1 = Parser::Instance()->returnUntillStrip( " ", line );
1255 if(EOF == sscanf(ID_1.c_str(), "%d", &co->id_1)) cerr << "error in parsing body" << endl;
1256
1257 // ROTATION
1258 string ROT_X_1 = Parser::Instance()->returnUntillStrip( " ", line );
1259 if(EOF == sscanf(ROT_X_1.c_str(), "%f", &co->rot_x_1)) cerr << "error in parsing body" << endl;
1260 string ROT_Y_1 = Parser::Instance()->returnUntillStrip( " ", line );
1261 if(EOF == sscanf(ROT_Y_1.c_str(), "%f", &co->rot_y_1)) cerr << "error in parsing body" << endl;
1262 string ROT_Z_1 = Parser::Instance()->returnUntillStrip( " ", line );
1263 if(EOF == sscanf(ROT_Z_1.c_str(), "%f", &co->rot_z_1)) cerr << "error in parsing body" << endl;
1264
1265 // POSITION
1266 string POS_X_1 = Parser::Instance()->returnUntillStrip( " ", line );
1267 if(EOF == sscanf(POS_X_1.c_str(), "%f", &co->pos_x_1)) cerr << "error in parsing body" << endl;
1268 string POS_Y_1 = Parser::Instance()->returnUntillStrip( " ", line );
1269 if(EOF == sscanf(POS_Y_1.c_str(), "%f", &co->pos_y_1)) cerr << "error in parsing body" << endl;
1270 string POS_Z_1 = Parser::Instance()->returnUntillStrip( " ", line );
1271 if(EOF == sscanf(POS_Z_1.c_str(), "%f", &co->pos_z_1)) cerr << "error in parsing body" << endl;
1272
1273 // LIMIT
1274 string LIMIT_1 = Parser::Instance()->returnUntillStrip( " ", line );
1275 if(EOF == sscanf(LIMIT_1.c_str(), "%f", &co->limit_1)) cerr << "error in parsing body" << endl;
1276
1277 // CONNECTION TO BODYPART 2
1278 string ID_2 = Parser::Instance()->returnUntillStrip( " ", line );
1279 if(EOF == sscanf(ID_2.c_str(), "%d", &co->id_2)) cerr << "error in parsing body" << endl;
1280
1281 // ROTATION
1282 string ROT_X_2 = Parser::Instance()->returnUntillStrip( " ", line );
1283 if(EOF == sscanf(ROT_X_2.c_str(), "%f", &co->rot_x_2)) cerr << "error in parsing body" << endl;
1284 string ROT_Y_2 = Parser::Instance()->returnUntillStrip( " ", line );
1285 if(EOF == sscanf(ROT_Y_2.c_str(), "%f", &co->rot_y_2)) cerr << "error in parsing body" << endl;
1286 string ROT_Z_2 = Parser::Instance()->returnUntillStrip( " ", line );
1287 if(EOF == sscanf(ROT_Z_2.c_str(), "%f", &co->rot_z_2)) cerr << "error in parsing body" << endl;
1288
1289 // POSITION
1290 string POS_X_2 = Parser::Instance()->returnUntillStrip( " ", line );
1291 if(EOF == sscanf(POS_X_2.c_str(), "%f", &co->pos_x_2)) cerr << "error in parsing body" << endl;
1292 string POS_Y_2 = Parser::Instance()->returnUntillStrip( " ", line );
1293 if(EOF == sscanf(POS_Y_2.c_str(), "%f", &co->pos_y_2)) cerr << "error in parsing body" << endl;
1294 string POS_Z_2 = Parser::Instance()->returnUntillStrip( " ", line );
1295 if(EOF == sscanf(POS_Z_2.c_str(), "%f", &co->pos_z_2)) cerr << "error in parsing body" << endl;
1296
1297 // LIMIT
1298 string LIMIT_2 = line;
1299 if(EOF == sscanf(LIMIT_2.c_str(), "%f", &co->limit_2)) cerr << "error in parsing body" << endl;
1300 }
1301 else if ( parseH->Instance()->beginMatchesStrip( "m ", line ) )
1302 {
1303 // m 99999 50, 50, 100
1304 // cerr << "constraint" << endl;
1305
1306 archMouth MO;
1307 archMouths.push_back( MO );
1308 archMouth *mo = &archMouths[archMouths.size()-1];
1309
1310 string ID = Parser::Instance()->returnUntillStrip( " ", line );
1311 if(EOF == sscanf(ID.c_str(), "%d", &mo->id)) cerr << "error in parsing body" << endl;
1312
1313 string X = Parser::Instance()->returnUntillStrip( " ", line );
1314 if(EOF == sscanf(X.c_str(), "%f", &mo->x)) cerr << "error in parsing body" << endl;
1315
1316 string Y = Parser::Instance()->returnUntillStrip( " ", line );
1317 if(EOF == sscanf(Y.c_str(), "%f", &mo->y)) cerr << "error in parsing body" << endl;
1318
1319 string Z = line;
1320 if(EOF == sscanf(Z.c_str(), "%f", &mo->z)) cerr << "error in parsing body" << endl;
1321 }
1322 line = parseH->Instance()->returnUntillStrip( "\n", contentCopy );
1323 }
1324 }
1325
1326
getArch()1327 string* BodyArch::getArch()
1328 {
1329 stringstream buf;
1330
1331 // neuron info
1332 buf << "color=" << color.r << "," << color.g << "," << color.b << ";\n";
1333 buf << "retinasize=" << retinasize << ";\n";
1334 for ( unsigned int i=0; i < archBodyparts.size(); i++ )
1335 {
1336 archBodypart *bp = &archBodyparts[i];
1337 buf << "b" << " " << bp->id << " " << "box" << " " << bp->materialID << " " << bp->x << " " << bp->y << " " << bp->z << "\n";
1338 }
1339
1340 for ( unsigned int i=0; i < archMouths.size(); i++ )
1341 {
1342 archMouth *mo = &archMouths[i];
1343 buf << "m" << " " << mo->id << " " << mo->x << " " << mo->y << " " << mo->z << "\n";
1344 }
1345
1346 for ( unsigned int i=0; i < archConstraints.size(); i++ )
1347 {
1348 archConstraint *co = &archConstraints[i];
1349 if ( co->isMouthConstraint )
1350 buf << "cm";
1351 else
1352 buf << "c";
1353 buf << " " << co->XYZ << " " << co->sign;
1354 buf << " " << co->constraint_id1 << " " << co->constraint_id2 << " ";
1355 buf << co->id_1 << " " << co->rot_x_1 << " " << co->rot_y_1 << " " << co->rot_z_1 << " " << co->pos_x_1 << " " << co->pos_y_1 << " " << co->pos_z_1 << " " << co->limit_1 << " ";
1356 buf << co->id_2 << " " << co->rot_x_2 << " " << co->rot_y_2 << " " << co->rot_z_2 << " " << co->pos_x_2 << " " << co->pos_y_2 << " " << co->pos_z_2 << " " << co->limit_2;
1357 buf << "\n";
1358 }
1359
1360 archBuffer = buf.str();
1361 return &archBuffer;
1362 }
1363
~BodyArch()1364 BodyArch::~BodyArch()
1365 {
1366 }
1367