// This file is a part of the Framsticks GDK. // Copyright (C) 2002-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. // Refer to http://www.framsticks.com/ for further information. #include "conv_f9.h" #include #include #include //ARRAY_LENGTH #define APPLY_DETERMINISTIC_BODY_NOISE //this representation easily produces perfectly vertical sticks that would stay upright forever. In most cases such infinite perfection is not desired, so we make the construct less perfect by perturbing its coordinates. GenoConv_f90::GenoConv_f90() { name = "Turtle3D-ortho encoding"; in_format = '9'; out_format = '0'; mapsupport = 0; //would be easy and nice to add! } const char* turtle_commands_f9 ="LRDUBF"; //const char* turtle_commandsX_f9="-+0000"; //const char* turtle_commandsY_f9="00-+00"; //const char* turtle_commandsZ_f9="0000-+"; SString GenoConv_f90::convert(SString &in, MultiMap *map) { vector vertices; XYZ_LOC current; Model m; m.open(); int recently_added=addSegment(m,vertices,current,0xDead); for(int i=0;i there were no valid turtle commands in the input genotype return ""; //so we return an invalid f0 genotype return m.getF0Geno().getGene(); } int GenoConv_f90::addSegment(Model &m,vector &vertices,const XYZ_LOC &new_vertex,int recently_added) { if (vertices.size()<1) //empty model? { return addNewVertex(m,vertices,new_vertex); } else { int vertex_here=findVertexAt(vertices,new_vertex); if (vertex_here<0) //need to create a new Part { vertex_here=addNewVertex(m,vertices,new_vertex); } //else there already exists a Part in new_vertex; new Joint may or may not be needed Part *p1=m.getPart(recently_added); Part *p2=m.getPart(vertex_here); if (m.findJoint(p1,p2)<0 && m.findJoint(p2,p1)<0) //new Joint needed? should always be true if we just created a new Part (vertex_here was <0) { m.addNewJoint(p1,p2); } return vertex_here; } } int GenoConv_f90::findVertexAt(vector &vertices,const XYZ_LOC &vertex) { for(int i=0;i &vertices,const XYZ_LOC &new_vertex) { Part *p=new Part; p->p.x=new_vertex.x; p->p.y=new_vertex.y; p->p.z=new_vertex.z; m.addPart(p); vertices.push_back(new_vertex); return vertices.size()-1; } double mix(int *colortab,int maxind,double ind) { int indpre=(int)ind; int indpost=indpre+1; if (indpost>maxind) indpost=maxind; int v1=colortab[indpre]; int v2=colortab[indpost]; double d1=ind-indpre; double d2=indpost-ind; double v=indpre==indpost?v1:d2*v1+d1*v2; //d1+d2==1 return v; } void GenoConv_f90::setColors(Model &m) //sets fixed (independent from genes) colors and widths on a model, purely for aesthetic purposes { //a rainbow on Joints: from the first one red, through middle green, to blue or violet - last static int r[]={1,1,0,0,0,1}; static int g[]={0,1,1,1,0,0}; static int b[]={0,0,0,1,1,1}; int maxind=ARRAY_LENGTH(r)-1; int joints_count=m.getJointCount(); for(int i=0;ivcolor.x=mix(r,maxind,ind); j->vcolor.y=mix(g,maxind,ind); j->vcolor.z=mix(b,maxind,ind); } int parts_count=m.getPartCount(); SList jlist; for(int i=0;ivcolor; if (count>5) count=5; //avoid too fat... p->vsize=0.3+count/15.0; //the more Joints is attached to a Part, the fatter it is p->vcolor=averagecolor/count; } } void GenoConv_f90::perturbPartLocations(Model &m) //deterministic "body noise", see APPLY_DETERMINISTIC_BODY_NOISE { for(int i=0;ip+=noise/1000; } }