// maxLevel maxId bBend shrink1 shrink2 maxTwigLen mainSpeed float[][] preset={ { 6, 5, 55*PI/180.0, 0.7, 0.88, 70, 1.0 }, { 7, 4, 70*PI/180.0, 0.8, 0.95, 40, 1.5 }, { 4, 6, 95*PI/180.0, 0.8, 0.95, 100, 1.0 }, { 8, 4, 45*PI/180.0, 0.5, 0.75, 60, 0.5 }, { 12, 3, 35*PI/180.0, 0.8, 0.85, 60, 0.33 } }; void getPreset(int i) { maxLevel=int(preset[i][0]); maxId=int(preset[i][1]); bBend=preset[i][2]; shrink1=preset[i][3]; shrink2=preset[i][4]; maxTwigLen=preset[i][5]; mainSpeed=preset[i][6]; } // PRESET variables: int maxLevel=6; // maximum depth level int maxId=5; // maximum number of children float bBend=55*PI/180.0; // bendangle from one twig to the next float shrink1=0.7; // minimum shrink factor to child twig float shrink2=0.88; // maximum shrink factor to child twig float maxTwigLen=70; // start twig length (used for getting pitch of twig) float mainSpeed=1.0; // pitching of all sounds plus growing speed boolean smoothing=false; // setting for smoothing on/off; float growLevel=0; // level for growing (related to depth level); boolean growing=true; // grow shrink process boolean shrinking=false; // grow shrink process TwigType[] tree=new TwigType[100000]; // tree object int shade=70<<16|70<<8|70; // shadecolor of tree int[] shadeBuf=new int[600*450]; int bgCol=244<<16|240<<8|255; // variables used for main loop: int nr_twigs; // total number of twigs (used for stepping through all twigs) boolean newTree; // checks if a new tree will be created float minTwigLen; // minimum twig length (used for getting pitch of twig) float rotY=0; // Y-rotation of whole tree float frameTime,lastMillis; // used for calculating frame time // sampler: Sampler Celesta=new Sampler(); Sample loopMusic; void setup() { size(600,450); background(bgCol); Sonia.start(this,22050); Celesta.initPolyphony(256); Celesta.initSounds(); loopMusic=new Sample("Cisloop2.aif"); loopMusic.setVolume(0); frameTime=1/25.0; lastMillis=millis(); newTree=true; } void mousePressed() { shrinking=true; growing=false; } void keyPressed() { if (key=='s'||key=='S') { smoothing=!smoothing; if (smoothing) {smooth();} else {noSmooth();} } } void loop() { if (newTree) { newTree=false; getPreset((int)random(5)); growLevel=0; minTwigLen=maxTwigLen; nr_twigs=0;twig(0,0,0,maxTwigLen,1,random(0.1,0.5),10*PI/180.0,random(TWO_PI),true); float sp=2*mainSpeed; if (sp>=1) {sp/=2;} loopMusic.stop();loopMusic.setVolume(0);loopMusic.setSpeed(sp);loopMusic.play();loopMusic.repeat(); } background(bgCol); lights(); //smooth(); translate(300,380); rotateY(rotY); rotY+=0.002; nr_twigs=0; twig(0,0,0,0,1,0,0,0,false); if (growing) { growLevel+=frameTime*mainSpeed; loopMusic.setVolume(0.35*growLevel/(float)maxLevel); if (growLevel>maxLevel) { growLevel=maxLevel; growing=false; } } if (shrinking) { growLevel-=frameTime*mainSpeed*4.0; loopMusic.setVolume(0.35*growLevel/(float)maxLevel); if (growLevel<0.0) { growLevel=0; shrinking=false; newTree=true; growing=true; } } frameTime=0.001*(millis()-lastMillis); lastMillis=millis(); } void twig(int id, float dir1, float dir2, float len, int lev, float frq, float amp, float pha, boolean create) { int children=0; if (create) { // creation phase: if (lenTWO_PI) {tree[nr_twigs].pha-=TWO_PI;} } else { len=tree[nr_twigs].len; amp=tree[nr_twigs].amp; } frq=tree[nr_twigs].frq; tree[nr_twigs].pha+=(frameTime*frq*TWO_PI); pha=tree[nr_twigs].pha; if (pha>TWO_PI&&growLevel>=lev-1) { tree[nr_twigs].pha-=TWO_PI; int i=int(35*(1.0-(tree[nr_twigs].len-minTwigLen)/(maxTwigLen-minTwigLen))); float vol=0.7*(len/(float)maxTwigLen)/(float)children; float pan=constrain(6*(2*screenX(0,0,0)/(float)width-1.0),-1,1); Celesta.playSample(i,vol,pan); } } nr_twigs++; push(); float sinus=amp*sin(pha); rotateZ(dir1+sinus); rotateY(dir2); float p=constrain(1.0-growLevel/(float)maxLevel,lev/(float)maxLevel,1); stroke(50-p*20,20+p*185,0,255); line(0,0,0,0,-len,0); translate(0,-len,0); if (lev