#include "bodyarch.h" BodyArch::BodyArch() { settings = Settings::Instance(); totalWeight = 0.0f; bodypartspacer = 2.2f; } void BodyArch::buildArch() { // string original; // original.append("b 99999 box 0 75 75 200\n"); // original.append("b 99998 box 0 75 75 200\n"); // original.append("b 99997 box 0 75 75 200\n"); // original.append("m 99999 50, 50, 100\n"); // 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"); // 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"); // 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"); // setArch(&original); // string fourlegged; // // body // fourlegged.append("b 99999 box 0 200 100 400\n"); // // 4 long legs // fourlegged.append("b 99998 box 0 150 40 40\n"); // fourlegged.append("b 99997 box 0 150 40 40\n"); // fourlegged.append("b 99996 box 0 150 40 40\n"); // fourlegged.append("b 99995 box 0 150 40 40\n"); // // mouth // fourlegged.append("m 99999 50, 50, 100\n"); // // connections // 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"); // 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"); // 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"); // 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"); // 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"); // setArch(&fourlegged); // string original; // original.append("b 1000 box 0 200 200 200\n"); // original.append("b 1001 box 0 100 100 100\n"); // original.append("b 1002 box 0 100 100 100\n"); // original.append("b 1003 box 0 100 100 100\n"); // original.append("b 1004 box 0 100 100 100\n"); // original.append("m 99999 50, 50, 100\n"); // // -x // 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"); // -z // 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"); // +z // 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"); // +x // 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"); // setArch(&original); // Create a central body archBodyparts.push_back( archBodypart() ); archBodypart *bp = &archBodyparts[archBodyparts.size()-1]; bp->id = 1000; bp->type = 0; bp->materialID = 0; bp->x = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") ); bp->y = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") ); bp->z = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") ); // add random more unsigned int runs = randgen->Instance()->get( 0, settings->getCVar("body_maxbodypartsatbuildtime")-1 ); // -1 -> central bodypart for ( unsigned int i=0; i < runs; i++ ) addRandomBodypart(); addRandomMouth(); } void BodyArch::removeBodypart(unsigned int id) { // cerr << "requested removal of bodypart id " << id << endl; // find constraints where this bodypart is id1, in order to remove connected bodyparts for ( unsigned int i = 0; i < archConstraints.size(); i++ ) { archConstraint* c = &archConstraints[i]; if ( c->id_1 == id ) { // cerr << " is connected to " << c->isMouthConstraint << " " << c->id_2 << endl; if ( c->isMouthConstraint ) removeMouth( findMouth(c->id_2) ); else removeBodypart( c->id_2 ); } } // cerr << "really removing " << id << " which is " << findBodypart( id ) << endl; archBodyparts.erase( archBodyparts.begin() + findBodypart(id) ); } void BodyArch::removeMouth(unsigned int id) { // cerr << "removing mouth " << id << endl; archMouths.erase(archMouths.begin()+id); } void BodyArch::addRandomMouth() { // Throw in a mouth archMouths.push_back( archMouth() ); archMouth* mo = &archMouths[archMouths.size()-1]; mo->id = 1000; mo->x = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") ); mo->y = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") ); mo->z = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") ); // Get it connected somehow unsigned int connID1 = randgen->Instance()->get( 0, archBodyparts.size()-1 ); unsigned int connID2 = archMouths.size()-1; addRandomConstraint(connID1, connID2, true); } void BodyArch::addRandomBodypart() { // Throw in a bodypart archBodyparts.push_back( archBodypart() ); archBodypart *bp = &archBodyparts[archBodyparts.size()-1]; bp->id = 0; // to avoid uninitialized id bp->id = getUniqueBodypartID(); bp->type = 0; bp->materialID = 0; bp->x = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") ); bp->y = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") ); bp->z = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") ); // Get it connected somehow unsigned int connID1 = randgen->Instance()->get( 0, archBodyparts.size()-1 ); unsigned int connID2 = archBodyparts.size()-1; while ( connID1 == connID2 ) connID1 = randgen->Instance()->get( 0, archBodyparts.size()-1 ); addRandomConstraint(connID1, connID2, false); } void BodyArch::addRandomConstraint(unsigned int connID1, unsigned int connID2, bool isMouth) { archConstraints.push_back( archConstraint() ); archConstraint *co = &archConstraints[archConstraints.size()-1]; co->isMouthConstraint = isMouth; // first initialize constraint id's co->constraint_id1 = 0; co->constraint_id2 = 0; co->constraint_id1 = getUniqueConstraintID(); co->constraint_id2 = getUniqueConstraintID(); co->id_1 = archBodyparts[ connID1 ].id; if ( isMouth ) co->id_2 = archMouths[ connID2 ].id; else co->id_2 = archBodyparts[ connID2 ].id; co->rot_x_1 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000; co->rot_y_1 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000; co->rot_z_1 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000; co->rot_x_2 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000; co->rot_y_2 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000; co->rot_z_2 = ((float)randgen->Instance()->get( 0, 1571 ) - 0) / 1000; randomConstraintPosition(co, 1, connID1); randomConstraintPosition(co, 2, connID2); co->limit_1 = (float)randgen->Instance()->get( 0, 7853 ) / -10000; co->limit_2 = -1.0f * co->limit_1; } void BodyArch::randomConstraintPosition(archConstraint* co, unsigned int OneOrTwo, unsigned int connID) { if ( OneOrTwo == 1 ) { co->XYZ = randgen->Instance()->get( 0, 2 ); co->sign = randgen->Instance()->get( 0, 1 ); if ( co->sign == 0 ) co->sign = -1; // now we know the plane to connect to, determine positions if ( co->XYZ == 0 ) // X { // ((x / 1000.0f) / 2) * 1.5f * co->sign = co->pos_x_1 = (archBodyparts[connID].x / 2000.0f) * co->sign * bodypartspacer; co->pos_y_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].y)*2) - archBodyparts[connID].y) / 1000; co->pos_z_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].z)*2) - archBodyparts[connID].z) / 1000; } else if ( co->XYZ == 1 ) // Y { co->pos_x_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].x)*2) - archBodyparts[connID].x) / 1000; co->pos_y_1 = (archBodyparts[connID].y / 2000.0f) * co->sign * bodypartspacer; co->pos_z_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].z)*2) - archBodyparts[connID].z) / 1000; } else // Z { co->pos_x_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].x)*2) - archBodyparts[connID].x) / 1000; co->pos_y_1 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].y)*2) - archBodyparts[connID].y) / 1000; co->pos_z_1 = (archBodyparts[connID].z / 2000.0f) * co->sign * bodypartspacer; } } else { int othersign = -1 * co->sign; if ( !co->isMouthConstraint ) { if ( co->XYZ == 0 ) // X { co->pos_x_2 = (archBodyparts[connID].x / 2000.0f) * othersign * bodypartspacer; co->pos_y_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].y)*2) - archBodyparts[connID].y) / 1000; co->pos_z_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].z)*2) - archBodyparts[connID].z) / 1000; } else if ( co->XYZ == 1 ) // Y { co->pos_x_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].x)*2) - archBodyparts[connID].x) / 1000; co->pos_y_2 = (archBodyparts[connID].y / 2000.0f) * othersign * bodypartspacer; co->pos_z_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].z)*2) - archBodyparts[connID].z) / 1000; } else // Z { co->pos_x_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].x)*2) - archBodyparts[connID].x) / 1000; co->pos_y_2 = ((float)randgen->Instance()->get( 0, (archBodyparts[connID].y)*2) - archBodyparts[connID].y) / 1000; co->pos_z_2 = (archBodyparts[connID].z / 2000.0f) * othersign * bodypartspacer; } } else { if ( co->XYZ == 0 ) // X { co->pos_x_2 = (archMouths[connID].x / 2000.0f) * othersign * bodypartspacer; co->pos_y_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].y)*2) - archMouths[connID].y) / 1000; co->pos_z_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].z)*2) - archMouths[connID].z) / 1000; } else if ( co->XYZ == 1 ) // Y { co->pos_x_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].x)*2) - archMouths[connID].x) / 1000; co->pos_y_2 = (archMouths[connID].y / 2000.0f) * othersign * bodypartspacer; co->pos_z_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].z)*2) - archMouths[connID].z) / 1000; } else // Z { co->pos_x_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].x)*2) - archMouths[connID].x) / 1000; co->pos_y_2 = ((float)randgen->Instance()->get( 0, (archMouths[connID].y)*2) - archMouths[connID].y) / 1000; co->pos_z_2 = (archMouths[connID].z / 2000.0f) * othersign * bodypartspacer; } } } } void BodyArch::mutate(unsigned int runs) { for ( unsigned int i=0; i < runs; i++ ) { unsigned int tsum = settings->getCVar("body_percentmutateeffectchangecolor") + settings->getCVar("body_percentmutateeffectchangecolor_slightly") + settings->getCVar("body_percentmutateeffectaddbodypart") + settings->getCVar("body_percentmutateeffectremovebodypart") + settings->getCVar("body_percentmutateeffectresizebodypart") + settings->getCVar("body_percentmutateeffectresizebodypart_slightly") + settings->getCVar("body_percentmutateeffectresizehead") + settings->getCVar("body_percentmutateeffectresizehead_slightly") + settings->getCVar("body_percentmutateeffectchangeconstraintlimits") + settings->getCVar("body_percentmutateeffectchangeconstraintlimits_slightly") + settings->getCVar("body_percentmutateeffectchangeconstraintangles") + settings->getCVar("body_percentmutateeffectchangeconstraintangles_slightly") + settings->getCVar("body_percentmutateeffectchangeconstraintposition") + settings->getCVar("body_percentmutateeffectchangeconstraintposition_slightly") + settings->getCVar("body_percentmutateeffectrepositionhead") ; unsigned int mode = randgen->Instance()->get(1,tsum); // CHANGE COLOR unsigned int modesum = settings->getCVar("body_percentmutateeffectchangecolor"); if ( mode <= modesum ) { // mutate color unsigned int ncolor = randgen->Instance()->get(0,2); if ( ncolor == 0 ) color.r = (float)RandGen::Instance()->get(0,100)/100.0f; else if ( ncolor == 1 ) color.g = (float)RandGen::Instance()->get(0,100)/100.0f; else if ( ncolor == 2 ) color.b = (float)RandGen::Instance()->get(0,100)/100.0f; continue; } // CHANGE COLOR SLIGHTLY modesum += settings->getCVar("body_percentmutateeffectchangecolor_slightly"); if ( mode <= modesum ) { // mutate color unsigned int ncolor = randgen->Instance()->get(0,2); unsigned int nweight = randgen->Instance()->get(1,10); float amount = 0.01 * nweight; if ( randgen->Instance()->get(0,1) == 0 ) amount *= -1; if ( ncolor == 0 ) color.r += amount; else if ( ncolor == 1 ) color.g += amount; else if ( ncolor == 2 ) color.b += amount; if ( color.r < 0.1f ) { float diff = 0.1f - color.r; color.r += diff; color.g += diff; color.b += diff; color.a += diff; } if ( color.g < 0.1f ) { float diff = 0.1f - color.g; color.r += diff; color.g += diff; color.b += diff; color.a += diff; } if ( color.b < 0.1f ) { float diff = 0.1f - color.b; color.r += diff; color.g += diff; color.b += diff; color.a += diff; } if ( color.r > 1.0f && color.g > 1.0f && color.b > 1.0f ) color.normalize(); continue; } // ADD BODYPART modesum += settings->getCVar("body_percentmutateeffectaddbodypart"); if ( mode <= modesum ) { if ( archBodyparts.size() < settings->getCVar("body_maxbodyparts") ) { // cerr << "adding bodypart" << endl; addRandomBodypart(); // cerr << "done adding bodypart" << endl; } else runs++; continue; } // REMOVE BODYPART modesum += settings->getCVar("body_percentmutateeffectremovebodypart"); if ( mode <= modesum ) { if ( archBodyparts.size() > 2 ) { // pick a random bodypart unsigned int bid = randgen->Instance()->get( 0, archBodyparts.size()-1 ); // if not main body, remove it if ( archBodyparts[bid].id != 1000 ) { // cerr << "removing bodypart " << bid << " id " << archBodyparts[bid].id << endl; removeBodypart( archBodyparts[bid].id ); // cerr << "removing obsolete constraints, expected errors:" << endl; for ( int i = 0; i < (int)archConstraints.size(); i++ ) { archConstraint* c = &archConstraints[i]; if ( findBodypart( c->id_1 ) == -1 ) { archConstraints.erase(archConstraints.begin()+i); i--; } else if ( c->isMouthConstraint && findMouth( c->id_2 ) == -1 ) { archConstraints.erase(archConstraints.begin()+i); i--; } else if ( !c->isMouthConstraint && findBodypart( c->id_2 ) == -1 ) { archConstraints.erase(archConstraints.begin()+i); i--; } } // cerr << "done removing obsolete constraints" << endl << endl; // cerr << "done removing bodypart" << endl; // re add mouth if needed if ( archMouths.size() == 0 ) addRandomMouth(); } else runs++; } else runs++; continue; } // RESIZE BODYPART modesum += settings->getCVar("body_percentmutateeffectresizebodypart"); if ( mode <= modesum ) { // cerr << "resize bodypart" << endl; // pick a random bodypart unsigned int bid = randgen->Instance()->get( 0, archBodyparts.size()-1 ); archBodypart *bp = &archBodyparts[bid]; unsigned int axismode = randgen->Instance()->get(0,2); if ( axismode == 0 ) bp->x = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") ); else if ( axismode == 1 ) bp->y = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") ); else bp->z = randgen->Instance()->get( settings->getCVar("body_minbodypartsize"), settings->getCVar("body_maxbodypartsize") ); // reposition the constraints back to the resized bodypart repositiontoConstraints(bp); // cerr << "done resize bodypart" << endl; continue; } // RESIZE BODYPART SLIGHTLY modesum += settings->getCVar("body_percentmutateeffectresizebodypart_slightly"); if ( mode <= modesum ) { // cerr << "resize bodypart slightly" << endl; // pick a random bodypart unsigned int bid = randgen->Instance()->get( 0, archBodyparts.size()-1 ); archBodypart* bp = &archBodyparts[bid]; unsigned int axismode = randgen->Instance()->get(0,2); unsigned int direction = randgen->Instance()->get(0,1); if ( axismode == 0 ) { if ( direction == 0 ) bp->x += randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 ); else bp->x -= randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 ); } else if ( axismode == 1 ) { if ( direction == 0 ) bp->y += randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 ); else bp->y -= randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 ); } else { if ( direction == 0 ) bp->z += randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 ); else bp->z -= randgen->Instance()->get( 1, settings->getCVar("body_maxbodypartsize") / 10 ); } // see that they didn't go over their limits if ( bp->x < settings->getCVar("body_minbodypartsize") ) bp->x = settings->getCVar("body_minbodypartsize"); else if ( bp->x > settings->getCVar("body_maxbodypartsize") ) bp->x = settings->getCVar("body_minbodypartsize"); if ( bp->y < settings->getCVar("body_minbodypartsize") ) bp->y = settings->getCVar("body_minbodypartsize"); else if ( bp->y > settings->getCVar("body_maxbodypartsize") ) bp->y = settings->getCVar("body_minbodypartsize"); if ( bp->z < settings->getCVar("body_minbodypartsize") ) bp->z = settings->getCVar("body_minbodypartsize"); else if ( bp->z > settings->getCVar("body_maxbodypartsize") ) bp->z = settings->getCVar("body_minbodypartsize"); // reposition the constraints back to the resized bodypart repositiontoConstraints(bp); // cerr << "done resize bodypart" << endl; continue; } // RESIZE HEAD modesum += settings->getCVar("body_percentmutateeffectresizehead"); if ( mode <= modesum ) { // cerr << "resize mouth" << endl; // pick a random head unsigned int mid = randgen->Instance()->get( 0, archMouths.size()-1 ); archMouth* head = &archMouths[mid]; unsigned int axismode = randgen->Instance()->get(0,2); if ( axismode == 0 ) head->x = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") ); else if ( axismode == 1 ) head->y = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") ); else head->z = randgen->Instance()->get( settings->getCVar("body_minheadsize"), settings->getCVar("body_maxheadsize") ); // reposition the constraints back to the resized bodypart repositiontoConstraints(head); // cerr << "done resize head" << endl; continue; } // RESIZE HEAD SLIGHTLY modesum += settings->getCVar("body_percentmutateeffectresizehead_slightly"); if ( mode <= modesum ) { // cerr << "resize head slightly" << endl; // pick a random head unsigned int mid = randgen->Instance()->get( 0, archMouths.size()-1 ); archMouth* head = &archMouths[mid]; unsigned int axismode = randgen->Instance()->get(0,2); unsigned int direction = randgen->Instance()->get(0,1); if ( axismode == 0 ) { if ( direction == 0 ) head->x += randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 ); else head->x -= randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 ); } else if ( axismode == 1 ) { if ( direction == 0 ) head->y += randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 ); else head->y -= randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 ); } else { if ( direction == 0 ) head->z += randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 ); else head->z -= randgen->Instance()->get( 1, settings->getCVar("body_maxheadsize") / 10 ); } // see that they didn't go over their limits if ( head->x < settings->getCVar("body_minheadsize") ) head->x = settings->getCVar("body_minheadsize"); else if ( head->x > settings->getCVar("body_maxheadsize") ) head->x = settings->getCVar("body_minheadsize"); if ( head->y < settings->getCVar("body_minheadsize") ) head->y = settings->getCVar("body_minheadsize"); else if ( head->y > settings->getCVar("body_maxheadsize") ) head->y = settings->getCVar("body_minheadsize"); if ( head->z < settings->getCVar("body_minheadsize") ) head->z = settings->getCVar("body_minheadsize"); else if ( head->z > settings->getCVar("body_maxheadsize") ) head->z = settings->getCVar("body_minheadsize"); // reposition the constraints back to the resized bodypart repositiontoConstraints(head); // cerr << "done resize head" << endl; continue; } // CHANGE CONSTRAINT LIMITS modesum += settings->getCVar("body_percentmutateeffectchangeconstraintlimits"); if ( mode <= modesum ) { // cerr << "changing constraint limits" << endl; unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 ); archConstraint* co = &archConstraints[cid]; co->limit_1 = (float)randgen->Instance()->get( 0, 7853 ) / -10000; co->limit_2 = -1.0f * co->limit_1; // cerr << "done changing constraint limits" << endl; continue; } // CHANGE CONSTRAINT LIMITS SLIGHTLY modesum += settings->getCVar("body_percentmutateeffectchangeconstraintlimits_slightly"); if ( mode <= modesum ) { // cerr << "changing constraint limits" << endl; unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 ); archConstraint* co = &archConstraints[cid]; unsigned int direction = randgen->Instance()->get(0,1); if ( direction == 0 ) co->limit_1 += 0.01f; else co->limit_1 -= 0.01f; // check limits limits, ya if ( co->limit_1 > 0.0f ) co->limit_1 = 0.0f; if ( co->limit_1 < -0.7853f ) co->limit_1 = -0.7853f; co->limit_2 = -1.0f * co->limit_1; // cerr << "done changing constraint limits" << endl; continue; } // CHANGE CONSTRAINT ANGLES modesum += settings->getCVar("body_percentmutateeffectchangeconstraintangles"); if ( mode <= modesum ) { // cerr << "changing constraint angles" << endl; unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 ); archConstraint* co = &archConstraints[cid]; co->rot_x_1 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000; co->rot_z_1 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000; co->rot_y_1 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000; co->rot_x_2 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000; co->rot_y_2 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000; co->rot_z_2 = ((float)randgen->Instance()->get( 0, 3141 ) - 1571) / 1000; // cerr << "done changing constraint angles" << endl; continue; } // CHANGE CONSTRAINT ANGLES SLIGHTLY modesum += settings->getCVar("body_percentmutateeffectchangeconstraintangles_slightly"); if ( mode <= modesum ) { // cerr << "changing constraint angles" << endl; unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 ); archConstraint* co = &archConstraints[cid]; unsigned int XYZ = randgen->Instance()->get(0,2); unsigned int direction = randgen->Instance()->get(0,1); if ( direction == 0 ) { if ( XYZ == 0 ) co->rot_x_1 += 0.01f; else if ( XYZ == 1 ) co->rot_y_1 += 0.01f; else co->rot_z_1 += 0.01f; } else { if ( XYZ == 0 ) co->rot_x_1 -= 0.01f; else if ( XYZ == 1 ) co->rot_y_1 -= 0.01f; else co->rot_z_1 -= 0.01f; } XYZ = randgen->Instance()->get(0,2); direction = randgen->Instance()->get(0,1); if ( direction == 0 ) { if ( XYZ == 0 ) co->rot_x_2 += 0.01f; else if ( XYZ == 1 ) co->rot_y_2 += 0.01f; else co->rot_z_2 += 0.01f; } else { if ( XYZ == 0 ) co->rot_x_2 -= 0.01f; else if ( XYZ == 1 ) co->rot_y_2 -= 0.01f; else co->rot_z_2 -= 0.01f; } if ( co->rot_x_1 < -0.1571f ) co->rot_x_1 = -0.1571f; if ( co->rot_x_1 > 0.1571f ) co->rot_x_1 = 0.1571f; if ( co->rot_y_1 < -0.1571f ) co->rot_y_1 = -0.1571f; if ( co->rot_y_1 > 0.1571f ) co->rot_y_1 = 0.1571f; if ( co->rot_z_1 < -0.1571f ) co->rot_z_1 = -0.1571f; if ( co->rot_z_1 > 0.1571f ) co->rot_z_1 = 0.1571f; if ( co->rot_x_2 < -0.1571f ) co->rot_x_2 = -0.1571f; if ( co->rot_x_2 > 0.1571f ) co->rot_x_2 = 0.1571f; if ( co->rot_y_2 < -0.1571f ) co->rot_y_2 = -0.1571f; if ( co->rot_y_2 > 0.1571f ) co->rot_y_2 = 0.1571f; if ( co->rot_z_2 < -0.1571f ) co->rot_z_2 = -0.1571f; if ( co->rot_z_2 > 0.1571f ) co->rot_z_2 = 0.1571f; // cerr << "done changing constraint angles" << endl; continue; } // REPOSITION A CONSTRAINT modesum += settings->getCVar("body_percentmutateeffectchangeconstraintposition"); if ( mode <= modesum ) { // cerr << "changing constraint position" << endl; unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 ); archConstraint* co = &archConstraints[cid]; int connID1 = findBodypart(co->id_1); int connID2; if ( co->isMouthConstraint ) connID2 = findMouth(co->id_2); else connID2 = findBodypart(co->id_2); // pick one of 2 bodies to reconnect unsigned int body1or2 = randgen->Instance()->get( 1, 2 ); if ( body1or2 == 1 ) randomConstraintPosition(co, 1, connID1); else randomConstraintPosition(co, 2, connID2); // cerr << "done changing constraint position" << endl; continue; } // REPOSITION A CONSTRAINT SLIGHTLY modesum += settings->getCVar("body_percentmutateeffectchangeconstraintposition_slightly"); if ( mode <= modesum ) { // cerr << "changing constraint position" << endl; unsigned int cid = randgen->Instance()->get( 0, archConstraints.size()-1 ); archConstraint* co = &archConstraints[cid]; int connID1 = findBodypart(co->id_1); int connID2; if ( co->isMouthConstraint ) connID2 = findMouth(co->id_2); else connID2 = findBodypart(co->id_2); // pick one of 2 bodies to reconnect unsigned int body1or2 = randgen->Instance()->get( 1, 2 ); unsigned int direction = randgen->Instance()->get( 0, 1 ); unsigned int axis1or2 = randgen->Instance()->get( 0, 1 ); if ( body1or2 == 1 ) { // now we know the plane to connect to, determine positions if ( co->XYZ == 0 ) { // X if ( direction == 0 ) { if ( axis1or2 == 0 ) co->pos_y_1 += archBodyparts[connID1].y / 100000; else co->pos_z_1 += archBodyparts[connID1].z / 100000; } else { if ( axis1or2 == 0 ) co->pos_y_1 -= archBodyparts[connID1].y / 100000; else co->pos_z_1 -= archBodyparts[connID1].z / 100000; } } else if ( co->XYZ == 1 ) { // Y if ( direction == 0 ) { if ( axis1or2 == 0 ) co->pos_x_1 += archBodyparts[connID1].x / 100000; else co->pos_z_1 += archBodyparts[connID1].z / 100000; } else { if ( axis1or2 == 0 ) co->pos_x_1 -= archBodyparts[connID1].x / 100000; else co->pos_z_1 -= archBodyparts[connID1].z / 100000; } } else { // Z if ( direction == 0 ) { if ( axis1or2 == 0 ) co->pos_x_1 += archBodyparts[connID1].x / 100000; else co->pos_y_1 += archBodyparts[connID1].y / 100000; } else { if ( axis1or2 == 0 ) co->pos_x_1 -= archBodyparts[connID1].x / 100000; else co->pos_y_1 -= archBodyparts[connID1].y / 100000; } } if ( co->pos_x_1 < archBodyparts[connID1].x/-2000 ) co->pos_x_1 = archBodyparts[connID1].x/-2000; if ( co->pos_x_1 > archBodyparts[connID1].x/2000 ) co->pos_x_1 = archBodyparts[connID1].x/2000; if ( co->pos_y_1 < archBodyparts[connID1].y/-2000 ) co->pos_y_1 = archBodyparts[connID1].y/-2000; if ( co->pos_y_1 > archBodyparts[connID1].y/2000 ) co->pos_y_1 = archBodyparts[connID1].y/2000; if ( co->pos_z_1 < archBodyparts[connID1].z/-2000 ) co->pos_z_1 = archBodyparts[connID1].z/-2000; if ( co->pos_z_1 > archBodyparts[connID1].z/2000 ) co->pos_z_1 = archBodyparts[connID1].z/2000; } else { if ( !co->isMouthConstraint ) { // now we know the plane to connect to, determine positions if ( co->XYZ == 0 ) { // X if ( direction == 0 ) { if ( axis1or2 == 0 ) co->pos_y_2 += archBodyparts[connID2].y / 100000; else co->pos_z_2 += archBodyparts[connID2].z / 100000; } else { if ( axis1or2 == 0 ) co->pos_y_2 -= archBodyparts[connID2].y / 100000; else co->pos_z_2 -= archBodyparts[connID2].z / 100000; } } else if ( co->XYZ == 1 ) { // Y if ( direction == 0 ) { if ( axis1or2 == 0 ) co->pos_x_2 += archBodyparts[connID2].x / 100000; else co->pos_z_2 += archBodyparts[connID2].z / 100000; } else { if ( axis1or2 == 0 ) co->pos_x_2 -= archBodyparts[connID2].x / 100000; else co->pos_z_2 -= archBodyparts[connID2].z / 100000; } } else { // Z if ( direction == 0 ) { if ( axis1or2 == 0 ) co->pos_x_2 += archBodyparts[connID2].x / 100000; else co->pos_y_2 += archBodyparts[connID2].y / 100000; } else { if ( axis1or2 == 0 ) co->pos_x_2 -= archBodyparts[connID2].x / 100000; else co->pos_y_2 -= archBodyparts[connID2].y / 100000; } } if ( co->pos_x_2 < archBodyparts[connID2].x/-2000 ) co->pos_x_2 = archBodyparts[connID2].x/-2000; if ( co->pos_x_2 > archBodyparts[connID2].x/2000 ) co->pos_x_2 = archBodyparts[connID2].x/2000; if ( co->pos_y_2 < archBodyparts[connID2].y/-2000 ) co->pos_y_2 = archBodyparts[connID2].y/-2000; if ( co->pos_y_2 > archBodyparts[connID2].y/2000 ) co->pos_y_2 = archBodyparts[connID2].y/2000; if ( co->pos_z_2 < archBodyparts[connID2].z/-2000 ) co->pos_z_2 = archBodyparts[connID2].z/-2000; if ( co->pos_z_2 > archBodyparts[connID2].z/2000 ) co->pos_z_2 = archBodyparts[connID2].z/2000; } else { if ( co->XYZ == 0 ) { // X if ( direction == 0 ) { if ( axis1or2 == 0 ) co->pos_y_2 += archMouths[connID2].y / 100000; else co->pos_z_2 += archMouths[connID2].z / 100000; } else { if ( axis1or2 == 0 ) co->pos_y_2 -= archMouths[connID2].y / 100000; else co->pos_z_2 -= archMouths[connID2].z / 100000; } } else if ( co->XYZ == 1 ) { // Y if ( direction == 0 ) { if ( axis1or2 == 0 ) co->pos_x_2 += archMouths[connID2].x / 100000; else co->pos_z_2 += archMouths[connID2].z / 100000; } else { if ( axis1or2 == 0 ) co->pos_x_2 -= archMouths[connID2].x / 100000; else co->pos_z_2 -= archMouths[connID2].z / 100000; } } else { // Z if ( direction == 0 ) { if ( axis1or2 == 0 ) co->pos_x_2 += archMouths[connID2].x / 100000; else co->pos_y_2 += archMouths[connID2].y / 100000; } else { if ( axis1or2 == 0 ) co->pos_x_2 -= archMouths[connID2].x / 100000; else co->pos_y_2 -= archMouths[connID2].y / 100000; } } if ( co->pos_x_2 < archMouths[connID2].x/-2000 ) co->pos_x_2 = archMouths[connID2].x/-2000; if ( co->pos_x_2 > archMouths[connID2].x/2000 ) co->pos_x_2 = archMouths[connID2].x/2000; if ( co->pos_y_2 < archMouths[connID2].y/-2000 ) co->pos_y_2 = archMouths[connID2].y/-2000; if ( co->pos_y_2 > archMouths[connID2].y/2000 ) co->pos_y_2 = archMouths[connID2].y/2000; if ( co->pos_z_2 < archMouths[connID2].z/-2000 ) co->pos_z_2 = archMouths[connID2].z/-2000; if ( co->pos_z_2 > archMouths[connID2].z/2000 ) co->pos_z_2 = archMouths[connID2].z/2000; } } // randomConstraintPosition(co, 2, connID2); // cerr << "done changing constraint position" << endl; continue; } // REMOVE AND ADD MOUTH modesum += settings->getCVar("body_percentmutateeffectrepositionhead"); if ( mode <= modesum ) { // cerr << "remove and add mouth" << endl; for ( int i = 0; i < (int)archConstraints.size(); i++ ) { archConstraint* c = &archConstraints[i]; if ( c->isMouthConstraint && c->id_2 == archMouths[0].id ) { archConstraints.erase(archConstraints.begin()+i); i--; } } removeMouth(0); addRandomMouth(); // cerr << "done remove and add mouth" << endl; continue; } // if we reach here, none were processed, decrease runs by 1 to make sure we get a hit if ( modesum > 0 ) runs++; } } void BodyArch::repositiontoConstraints( archBodypart* bp ) { // reposition the constraints back to the resized bodypart / mouth for ( int i = 0; i < (int)archConstraints.size(); i++ ) { archConstraint* co = &archConstraints[i]; if ( findBodypart( co->id_1 ) == (int)bp->id ) { if ( co->XYZ == 0 ) // X co->pos_x_1 = (bp->x / 2000.0f) * co->sign * bodypartspacer; else if ( co->XYZ == 1 ) // Y co->pos_y_1 = (bp->y / 2000.0f) * co->sign * bodypartspacer; else if ( co->XYZ == 2 ) // Z co->pos_z_1 = (bp->z / 2000.0f) * co->sign * bodypartspacer; } else if ( !co->isMouthConstraint && findBodypart( co->id_2 ) == (int)bp->id ) { int othersign = -1 * co->sign; if ( co->XYZ == 0 ) // X co->pos_x_2 = (bp->x / 2000.0f) * othersign * bodypartspacer; else if ( co->XYZ == 1 ) // Y co->pos_y_2 = (bp->y / 2000.0f) * othersign * bodypartspacer; else if ( co->XYZ == 2 ) // Z co->pos_z_2 = (bp->z / 2000.0f) * othersign * bodypartspacer; } } } void BodyArch::repositiontoConstraints( archMouth* bp ) { // reposition the constraints back to the resized bodypart / mouth for ( int i = 0; i < (int)archConstraints.size(); i++ ) { archConstraint* co = &archConstraints[i]; if ( co->isMouthConstraint && findBodypart( co->id_2 ) == (int)bp->id ) { int othersign = -1 * co->sign; if ( co->XYZ == 0 ) // X co->pos_x_2 = (bp->x / 2000.0f) * othersign * bodypartspacer; else if ( co->XYZ == 1 ) // Y co->pos_y_2 = (bp->y / 2000.0f) * othersign * bodypartspacer; else if ( co->XYZ == 2 ) // Z co->pos_z_2 = (bp->z / 2000.0f) * othersign * bodypartspacer; } } } int BodyArch::findBodypart( unsigned int id ) { for ( unsigned int i=0; i < archBodyparts.size(); i++ ) { if ( archBodyparts[i].id == id ) { return i; } } // cerr << " NOT GOOD: cannot find a bodypart for the id " << id << endl; return -1; } int BodyArch::findMouth( unsigned int id ) { for ( unsigned int i=0; i < archMouths.size(); i++ ) { if ( archMouths[i].id == id ) { return i; } } // cerr << " NOT GOOD " << endl; // cerr << " NOT GOOD: cannot find a mouth for the id " << id << endl; return -1; } unsigned int BodyArch::getUniqueBodypartID() { unsigned int id = 1000; bool found = true; while ( found ) { found = false; for ( unsigned int i = 0; i < archBodyparts.size() && !found; i++ ) if ( archBodyparts[i].id == id ) { found = true; id++; } } return id; } unsigned int BodyArch::getUniqueConstraintID() { unsigned int id = 1000; bool found = true; while ( found ) { found = false; for ( unsigned int i = 0; i < archConstraints.size() && !found; i++ ) { if ( archConstraints[i].constraint_id1 == id || archConstraints[i].constraint_id2 == id ) { found = true; id++; } } } return id; } void BodyArch::copyFrom(const BodyArch* otherBody) { color = otherBody->color; retinasize = otherBody->retinasize; for ( unsigned int i=0; i < otherBody->archBodyparts.size(); i++ ) { const archBodypart *obp = &otherBody->archBodyparts[i]; archBodyparts.push_back( archBodypart() ); archBodypart *bp = &archBodyparts[archBodyparts.size()-1]; bp->id = obp->id; bp->type = obp->type; bp->materialID = obp->materialID; bp->x = obp->x; bp->y = obp->y; bp->z = obp->z; } for ( unsigned int i=0; i < otherBody->archMouths.size(); i++ ) { const archMouth *omo = &otherBody->archMouths[i]; archMouths.push_back( archMouth() ); archMouth *mo = &archMouths[archMouths.size()-1]; mo->id = omo->id; mo->x = omo->x; mo->y = omo->y; mo->z = omo->z; } for ( unsigned int i=0; i < otherBody->archConstraints.size(); i++ ) { const archConstraint *oco = &otherBody->archConstraints[i]; archConstraints.push_back( archConstraint() ); archConstraint *co = &archConstraints[archConstraints.size()-1]; co->isMouthConstraint = oco->isMouthConstraint; co->constraint_id1 = oco->constraint_id1; co->constraint_id2 = oco->constraint_id2; co->XYZ = oco->XYZ; co->sign = oco->sign; co->id_1 = oco->id_1; co->id_2 = oco->id_2; co->rot_x_1 = oco->rot_x_1; co->rot_x_2 = oco->rot_x_2; co->rot_y_1 = oco->rot_y_1; co->rot_y_2 = oco->rot_y_2; co->rot_z_1 = oco->rot_z_1; co->rot_z_2 = oco->rot_z_2; co->pos_x_1 = oco->pos_x_1; co->pos_x_2 = oco->pos_x_2; co->pos_y_1 = oco->pos_y_1; co->pos_y_2 = oco->pos_y_2; co->pos_z_1 = oco->pos_z_1; co->pos_z_2 = oco->pos_z_2; co->limit_1 = oco->limit_1; co->limit_2 = oco->limit_2; } } void BodyArch::setArch(string* content) { // cerr << *content << endl; string contentCopy = *content; string line = parseH->Instance()->returnUntillStrip( "\n", contentCopy ); while ( !line.empty() ) { if ( Parser::Instance()->beginMatchesStrip( "color=", line ) ) { string R = Parser::Instance()->returnUntillStrip( ",", line ); string G = Parser::Instance()->returnUntillStrip( ",", line ); string B = Parser::Instance()->returnUntillStrip( ";", line ); if(EOF == sscanf(R.c_str(), "%f", &color.r)) cerr << "ERROR INSERTING CRITTER (colorR)" << endl; if(EOF == sscanf(G.c_str(), "%f", &color.g)) cerr << "ERROR INSERTING CRITTER (colorG)" << endl; if(EOF == sscanf(B.c_str(), "%f", &color.b)) cerr << "ERROR INSERTING CRITTER (colorB)" << endl; color.a = 0.0f; } else if ( Parser::Instance()->beginMatchesStrip( "retinasize=", line ) ) { string RES = Parser::Instance()->returnUntillStrip( ";", line ); //cerr << "RES: " << RES << endl; if(EOF == sscanf(RES.c_str(), "%d", &retinasize)) cerr << "ERROR INSERTING CRITTER" << endl; } else if ( parseH->Instance()->beginMatchesStrip( "b ", line ) ) { // b 99999 box 0 75 75 200 // cerr << "bodypart" << endl; archBodyparts.push_back( archBodypart() ); archBodypart *bp = &archBodyparts[archBodyparts.size()-1]; string bodypartID = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(bodypartID.c_str(), "%d", &bp->id)) cerr << "error in parsing body" << endl; string bodypartShape = Parser::Instance()->returnUntillStrip( " ", line ); if ( bodypartShape == "box" ) { // type = box bp->type = 0; // materialID string materialID = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(materialID.c_str(), "%d", &bp->materialID)) cerr << "error in parsing body" << endl; // dimesions X Y Z string X = Parser::Instance()->returnUntillStrip( " ", line ); string Y = Parser::Instance()->returnUntillStrip( " ", line ); string Z = line; if(EOF == sscanf(X.c_str(), "%f", &bp->x)) cerr << "error in parsing body" << endl; if(EOF == sscanf(Y.c_str(), "%f", &bp->y)) cerr << "error in parsing body" << endl; if(EOF == sscanf(Z.c_str(), "%f", &bp->z)) cerr << "error in parsing body" << endl; /* cerr << endl << " id " << bp->id << endl; cerr << " type " << bp->type << endl; cerr << " material " << bp->materialID << endl; cerr << " x " << bp->x << endl; cerr << " y " << bp->y << endl; cerr << " z " << bp->z << endl;*/ } } else if ( parseH->Instance()->beginMatchesStrip( "c ", line ) ) { // c 99999 1.5707963 0 0 0 0 -0.25 99998 1.5707963 0 0 0 0 0.25 // 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 // cerr << "constraint" << endl; archConstraint CO; archConstraints.push_back( CO ); archConstraint *co = &archConstraints[archConstraints.size()-1]; // XYZ & sign string XYZ = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(XYZ.c_str(), "%d", &co->XYZ)) cerr << "error in parsing body" << endl; string SIGN = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(SIGN.c_str(), "%d", &co->sign)) cerr << "error in parsing body" << endl; // CONSTRAINT IDS string ID = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ID.c_str(), "%d", &co->constraint_id1)) cerr << "error in parsing body" << endl; ID = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ID.c_str(), "%d", &co->constraint_id2)) cerr << "error in parsing body" << endl; // CONNECTION TO BODYPART 1 string ID_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ID_1.c_str(), "%d", &co->id_1)) cerr << "error in parsing body" << endl; // ROTATION string ROT_X_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_X_1.c_str(), "%f", &co->rot_x_1)) cerr << "error in parsing body" << endl; string ROT_Y_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_Y_1.c_str(), "%f", &co->rot_y_1)) cerr << "error in parsing body" << endl; string ROT_Z_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_Z_1.c_str(), "%f", &co->rot_z_1)) cerr << "error in parsing body" << endl; // POSITION string POS_X_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_X_1.c_str(), "%f", &co->pos_x_1)) cerr << "error in parsing body" << endl; string POS_Y_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_Y_1.c_str(), "%f", &co->pos_y_1)) cerr << "error in parsing body" << endl; string POS_Z_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_Z_1.c_str(), "%f", &co->pos_z_1)) cerr << "error in parsing body" << endl; // LIMIT string LIMIT_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(LIMIT_1.c_str(), "%f", &co->limit_1)) cerr << "error in parsing body" << endl; // CONNECTION TO BODYPART 2 string ID_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ID_2.c_str(), "%d", &co->id_2)) cerr << "error in parsing body" << endl; // ROTATION string ROT_X_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_X_2.c_str(), "%f", &co->rot_x_2)) cerr << "error in parsing body" << endl; string ROT_Y_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_Y_2.c_str(), "%f", &co->rot_y_2)) cerr << "error in parsing body" << endl; string ROT_Z_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_Z_2.c_str(), "%f", &co->rot_z_2)) cerr << "error in parsing body" << endl; // POSITION string POS_X_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_X_2.c_str(), "%f", &co->pos_x_2)) cerr << "error in parsing body" << endl; string POS_Y_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_Y_2.c_str(), "%f", &co->pos_y_2)) cerr << "error in parsing body" << endl; string POS_Z_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_Z_2.c_str(), "%f", &co->pos_z_2)) cerr << "error in parsing body" << endl; // LIMIT string LIMIT_2 = line; if(EOF == sscanf(LIMIT_2.c_str(), "%f", &co->limit_2)) cerr << "error in parsing body" << endl; } else if ( parseH->Instance()->beginMatchesStrip( "cm ", line ) ) { // cm 99999 1.5707963 0 0 0 0 -0.25 99998 1.5707963 0 0 0 0 0.25 // cerr << "constraint" << endl; archConstraint CO; archConstraints.push_back( CO ); archConstraint *co = &archConstraints[archConstraints.size()-1]; co->isMouthConstraint = true; // XYZ & sign string XYZ = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(XYZ.c_str(), "%d", &co->XYZ)) cerr << "error in parsing body" << endl; string SIGN = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(SIGN.c_str(), "%d", &co->sign)) cerr << "error in parsing body" << endl; // CONSTRAINT IDS string ID = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ID.c_str(), "%d", &co->constraint_id1)) cerr << "error in parsing body" << endl; ID = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ID.c_str(), "%d", &co->constraint_id2)) cerr << "error in parsing body" << endl; // CONNECTION TO BODYPART 1 string ID_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ID_1.c_str(), "%d", &co->id_1)) cerr << "error in parsing body" << endl; // ROTATION string ROT_X_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_X_1.c_str(), "%f", &co->rot_x_1)) cerr << "error in parsing body" << endl; string ROT_Y_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_Y_1.c_str(), "%f", &co->rot_y_1)) cerr << "error in parsing body" << endl; string ROT_Z_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_Z_1.c_str(), "%f", &co->rot_z_1)) cerr << "error in parsing body" << endl; // POSITION string POS_X_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_X_1.c_str(), "%f", &co->pos_x_1)) cerr << "error in parsing body" << endl; string POS_Y_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_Y_1.c_str(), "%f", &co->pos_y_1)) cerr << "error in parsing body" << endl; string POS_Z_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_Z_1.c_str(), "%f", &co->pos_z_1)) cerr << "error in parsing body" << endl; // LIMIT string LIMIT_1 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(LIMIT_1.c_str(), "%f", &co->limit_1)) cerr << "error in parsing body" << endl; // CONNECTION TO BODYPART 2 string ID_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ID_2.c_str(), "%d", &co->id_2)) cerr << "error in parsing body" << endl; // ROTATION string ROT_X_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_X_2.c_str(), "%f", &co->rot_x_2)) cerr << "error in parsing body" << endl; string ROT_Y_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_Y_2.c_str(), "%f", &co->rot_y_2)) cerr << "error in parsing body" << endl; string ROT_Z_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ROT_Z_2.c_str(), "%f", &co->rot_z_2)) cerr << "error in parsing body" << endl; // POSITION string POS_X_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_X_2.c_str(), "%f", &co->pos_x_2)) cerr << "error in parsing body" << endl; string POS_Y_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_Y_2.c_str(), "%f", &co->pos_y_2)) cerr << "error in parsing body" << endl; string POS_Z_2 = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(POS_Z_2.c_str(), "%f", &co->pos_z_2)) cerr << "error in parsing body" << endl; // LIMIT string LIMIT_2 = line; if(EOF == sscanf(LIMIT_2.c_str(), "%f", &co->limit_2)) cerr << "error in parsing body" << endl; } else if ( parseH->Instance()->beginMatchesStrip( "m ", line ) ) { // m 99999 50, 50, 100 // cerr << "constraint" << endl; archMouth MO; archMouths.push_back( MO ); archMouth *mo = &archMouths[archMouths.size()-1]; string ID = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(ID.c_str(), "%d", &mo->id)) cerr << "error in parsing body" << endl; string X = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(X.c_str(), "%f", &mo->x)) cerr << "error in parsing body" << endl; string Y = Parser::Instance()->returnUntillStrip( " ", line ); if(EOF == sscanf(Y.c_str(), "%f", &mo->y)) cerr << "error in parsing body" << endl; string Z = line; if(EOF == sscanf(Z.c_str(), "%f", &mo->z)) cerr << "error in parsing body" << endl; } line = parseH->Instance()->returnUntillStrip( "\n", contentCopy ); } } string* BodyArch::getArch() { stringstream buf; // neuron info buf << "color=" << color.r << "," << color.g << "," << color.b << ";\n"; buf << "retinasize=" << retinasize << ";\n"; for ( unsigned int i=0; i < archBodyparts.size(); i++ ) { archBodypart *bp = &archBodyparts[i]; buf << "b" << " " << bp->id << " " << "box" << " " << bp->materialID << " " << bp->x << " " << bp->y << " " << bp->z << "\n"; } for ( unsigned int i=0; i < archMouths.size(); i++ ) { archMouth *mo = &archMouths[i]; buf << "m" << " " << mo->id << " " << mo->x << " " << mo->y << " " << mo->z << "\n"; } for ( unsigned int i=0; i < archConstraints.size(); i++ ) { archConstraint *co = &archConstraints[i]; if ( co->isMouthConstraint ) buf << "cm"; else buf << "c"; buf << " " << co->XYZ << " " << co->sign; buf << " " << co->constraint_id1 << " " << co->constraint_id2 << " "; 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 << " "; 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; buf << "\n"; } archBuffer = buf.str(); return &archBuffer; } BodyArch::~BodyArch() { }