{"id":705,"date":"2012-04-17T06:55:07","date_gmt":"2012-04-17T06:55:07","guid":{"rendered":"http:\/\/www.new-territories.com\/blog\/rmit.uts\/?page_id=705"},"modified":"2012-04-30T02:50:47","modified_gmt":"2012-04-30T02:50:47","slug":"serra-terra_code","status":"publish","type":"page","link":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/code\/serra-terra_code\/","title":{"rendered":"serra t[err]a_code"},"content":{"rendered":"<p>\/*<br \/>\n* Copyright (c) 2012 Gwyllim Jahn<br \/>\n* http:\/\/scripts.crida.net\/gh<\/p>\n<p>* Developed By Gwyllim Jahn, Kathryn McKenzie and Sarah Papadopoullos<br \/>\n* during the 2012 RMIT nCertainties studio.<br \/>\n*<br \/>\n* This code makes extensive use of several freely distributed<br \/>\n* processing libraries \u2013 thankyou especially to toxi.<\/p>\n<p>*This code is free software; you can redistribute it and\/or<br \/>\n* modify it under the terms of the GNU Lesser General Public<br \/>\n* License as published by the Free Software Foundation; either<br \/>\n* version 2.1 of the License, or (at your option) any later version.<br \/>\n*<br \/>\n* http:\/\/creativecommons.org\/licenses\/LGPL\/2.1\/<br \/>\n*<br \/>\n* This code is distributed in the hope that it will be useful,<br \/>\n* but WITHOUT ANY WARRANTY; without even the implied warranty of<br \/>\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU<br \/>\n* Lesser General Public License for more details.<br \/>\n*<br \/>\n*\/<\/p>\n<ul>\n<li>\/\/\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013Bansia Pumps v2\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013\/\/<\/li>\n<\/ul>\n<p>import processing.pdf.*;<\/p>\n<p>import processing.video.*;<\/p>\n<p>import controlP5.*;<\/p>\n<p>import processing.dxf.*;<\/p>\n<p>import toxi.geom.*;<\/p>\n<p>import toxi.volume.*;<\/p>\n<p>import peasy.org.apache.commons.math.*;<\/p>\n<p>import peasy.*;<\/p>\n<p>import peasy.org.apache.commons.math.geometry.*;<\/p>\n<p>import processing.opengl.*;<\/p>\n<p>\/\/ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-GLOBALS<\/p>\n<p>int DX=900;<\/p>\n<p>int DY=900;<\/p>\n<p>int DZ=300;<\/p>\n<p>float density = 0.3;<\/p>\n<p>VolumetricSpaceArray volume;<\/p>\n<p>VolumetricBrush brush;<\/p>\n<p>boolean saveRaw = false;<\/p>\n<p>boolean paused = false;<\/p>\n<p>PeasyCam cam;<\/p>\n<p>ControlP5 controlP5;<\/p>\n<p>ControlWindow controlWindow;<\/p>\n<p>MovieMaker mm;<\/p>\n<p>int numAgents = 40;<\/p>\n<p>boolean record = false;<\/p>\n<p>boolean filming = false;<\/p>\n<p>\/\/HashMap&lt;String, ArrayList&lt;Agent&gt;&gt; aMap =new HashMap&lt;String, ArrayList&lt;Agent&gt;&gt; ();<\/p>\n<p>\/\/MultiMap agentPop = MultiValueMap.decorate(aMap);<\/p>\n<p>ArrayList&lt;Agent&gt; agentPop = new ArrayList&lt;Agent&gt;();<\/p>\n<p>ArrayList&lt;SapMonster&gt; sapPop = new ArrayList&lt;SapMonster&gt;();<\/p>\n<p>ArrayList&lt;TreeAttractor&gt;forest = new ArrayList&lt;TreeAttractor&gt;();<\/p>\n<p>ArrayList&lt;Agent&gt;addList = new ArrayList&lt;Agent&gt;();<\/p>\n<p>Boolean drawPts = false;<\/p>\n<p>Boolean drawSingle = false;<\/p>\n<p>int ct =0;<\/p>\n<p>\/\/agent variables<\/p>\n<p>\/\/number of points to draw a trail with<\/p>\n<p>int trailLength = 100;<\/p>\n<p>float agentSpeed = 0.5;<\/p>\n<p>\/\/distance between trail points<\/p>\n<p>int dropSpacing = 5;<\/p>\n<p>\/\/size of field to spawn agents<\/p>\n<p>float spawnSizeXY = 10;<\/p>\n<p>float aAttract = 1;<\/p>\n<p>float aAlign = 0.03;<\/p>\n<p>float aRepel = 3;<\/p>\n<p>float aAccel = 0.02;<\/p>\n<p>\/\/NEW VARIABLES<\/p>\n<p>float maxAgentSize = 15;<\/p>\n<p>float increaseSize = 0.3;<\/p>\n<p>float distToTree = 10;<\/p>\n<p>int firstTree = 7;<\/p>\n<p>\/\/set iso density to spawn size<\/p>\n<p>Vec3D SCALE=new Vec3D(450,450,300);<\/p>\n<p>float sX = SCALE.x\/DX;<\/p>\n<p>float sY = SCALE.y\/DY;<\/p>\n<p>float sZ = SCALE.z\/DZ;<\/p>\n<p>\/\/camera look at point<\/p>\n<p>float camx =200;<\/p>\n<p>float camy = 200;<\/p>\n<p>float camz = 0;<\/p>\n<p>\/\/resolution of the dots<\/p>\n<p>int r = 2;<\/p>\n<p>\/\/ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-SETUP<\/p>\n<p>void setup(){<\/p>\n<p>size(700,700,P3D);<\/p>\n<p>cam = new PeasyCam(this,camx,camy,camz, 400);<\/p>\n<p>stroke(255);<\/p>\n<p>mm = new MovieMaker(this, width, height, &#8220;drawing.mov&#8221;, 30, MovieMaker.ANIMATION, MovieMaker.HIGH);<\/p>\n<p>\/\/load in the tree locations<\/p>\n<p>importLandscape();<\/p>\n<p>\/\/spawn all the agents<\/p>\n<p>spawn();<\/p>\n<p>\/\/setup the controllers<\/p>\n<p>setupP5();<\/p>\n<p>\/\/volume brush stuff<\/p>\n<p>volume=new VolumetricSpaceArray(SCALE,DX,DY,DZ);<\/p>\n<p>brush=new RoundBrush(volume,5);<\/p>\n<p>}<\/p>\n<p>\/\/ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-DRAW LOOP<\/p>\n<p>void draw(){<\/p>\n<p>background(0);<\/p>\n<p>\/\/this draws the actual voxels as points &#8211; very slow&#8230;<\/p>\n<p>\/\/only useful for checking if things are working.<\/p>\n<p>if(record){<\/p>\n<p>beginRaw(PDF,&#8221;test_####.pdf&#8221;);<\/p>\n<p>}<\/p>\n<p>if(drawPts){<\/p>\n<p>drawVox();<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;GUTS<\/p>\n<p>for (Agent a :agentPop){<\/p>\n<p>a.run();<\/p>\n<p>}<\/p>\n<p>for (TreeAttractor t :forest){<\/p>\n<p>t.render();<\/p>\n<p>}<\/p>\n<p>ArrayList&lt;Integer&gt; removeList = new ArrayList&lt;Integer&gt;();<\/p>\n<p>int c =0;<\/p>\n<p>for (SapMonster s :sapPop){<\/p>\n<p>if(s.alive){<\/p>\n<p>s.run();<\/p>\n<p>}else{<\/p>\n<p>removeList.add(c);<\/p>\n<p>}<\/p>\n<p>c++;<\/p>\n<p>}<\/p>\n<p>sapPop.removeAll(removeList);<\/p>\n<p>if(addList.size()&gt;0){<\/p>\n<p>for (Agent a:addList){<\/p>\n<p>agentPop.add(a);<\/p>\n<p>}<\/p>\n<p>addList = new ArrayList&lt;Agent&gt;();<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;GUTS<\/p>\n<p>if(record){<\/p>\n<p>endRaw();<\/p>\n<p>record = false;<\/p>\n<p>}<\/p>\n<p>if(filming)mm.addFrame();<\/p>\n<p>if (saveRaw) {<\/p>\n<p>\/\/ save mesh as STL or OBJ file<\/p>\n<p>GsaveData(volume,&#8221;F:\/gsave&#8221;+ct+&#8221;.raw&#8221;);<\/p>\n<p>saveRaw=false;<\/p>\n<p>ct++;<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>void keyPressed(){<\/p>\n<p>\/\/s saves a dxf<\/p>\n<p>if (key == &#8216;s&#8217;) {<\/p>\n<p>record = !record;<\/p>\n<p>}<\/p>\n<p>if(key == &#8216;v&#8217;){<\/p>\n<p>saveRaw = !saveRaw;<\/p>\n<p>}<\/p>\n<p>\/\/c screen capture.<\/p>\n<p>if (key == &#8216;c&#8217;){<\/p>\n<p>saveFrame(&#8220;pic_####.png&#8221;);<\/p>\n<p>}<\/p>\n<p>if(key == &#8216;m&#8217;){<\/p>\n<p>if(!filming) {<\/p>\n<p>filming = true;<\/p>\n<p>}else{<\/p>\n<p>filming = false;<\/p>\n<p>mm.finish(); \/\/ Finish the movie if space bar is pressed!<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>if (key == &#8216;r&#8217;){<\/p>\n<p>\/\/reset the sketch<\/p>\n<p>importLandscape();<\/p>\n<p>spawn();<\/p>\n<p>}<\/p>\n<p>if (key == &#8216;d&#8217;){<\/p>\n<p>drawPts = !drawPts;<\/p>\n<p>}<\/p>\n<p>if (key == &#8216;p&#8217;){<\/p>\n<p>paused = !paused;<\/p>\n<p>}<\/p>\n<p>if (key == &#8216;1&#8217;){<\/p>\n<p>drawSingle = !drawSingle;<\/p>\n<p>print(drawSingle);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>\/\/\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 Agent \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013\/\/<\/p>\n<p>\/\/simple agent class to interact with the data<\/p>\n<p>\/\/field and other agents<\/p>\n<p>class Agent {<\/p>\n<p>Vec3D loc,vel,acc;<\/p>\n<p>ArrayList&lt;Vec3D&gt; trail;<\/p>\n<p>float aSize;<\/p>\n<p>float dropNum;<\/p>\n<p>boolean ruptured;<\/p>\n<p>TreeAttractor parent;<\/p>\n<p>float aX,aY,aZ;<\/p>\n<p>Agent(Vec3D _loc, Vec3D _vel, TreeAttractor _parent){<\/p>\n<p>loc = _loc;<\/p>\n<p>vel = _vel;<\/p>\n<p>acc = new Vec3D(0,0,0);<\/p>\n<p>trail = new ArrayList&lt;Vec3D&gt;();<\/p>\n<p>dropNum = 0;<\/p>\n<p>ruptured = false;<\/p>\n<p>aSize =1;<\/p>\n<p>parent = _parent;<\/p>\n<p>aX = aY= aZ=0;<\/p>\n<p>}<\/p>\n<p>void run(){<\/p>\n<p>if(!paused){<\/p>\n<p>\/\/acc = new Vec3D(0,0,0);<\/p>\n<p>getGridPos();<\/p>\n<p>if(parent.volume&gt;0){<\/p>\n<p>aSize = 1;<\/p>\n<p>searchAgents();<\/p>\n<p>}else{<\/p>\n<p>if(aSize&gt;1)aSize-=0.2;<\/p>\n<p>searchTrees();<\/p>\n<p>}<\/p>\n<p>update();<\/p>\n<p>volBrushLocation();<\/p>\n<p>}<\/p>\n<p>if(!drawPts){<\/p>\n<p>render();<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Basic Flock Function.<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void searchAgents(){<\/p>\n<p>\/\/reset accel<\/p>\n<p>for (Agent a:agentPop){<\/p>\n<p>\/\/get essential variables<\/p>\n<p>Vec3D diff = a.loc.sub(loc.copy());<\/p>\n<p>float d = diff.magnitude();<\/p>\n<p>if(d&lt;80&amp;&amp;d&gt;0){<\/p>\n<p>attract(diff.copy(),d); \/\/attract to neighbour<\/p>\n<p>align(a.vel.copy(),d); \/\/align with neighbour<\/p>\n<p>if(d&lt;10) {<\/p>\n<p>repel(diff.copy(),d); \/\/avoid neighbour<\/p>\n<p>if(loc.z&gt;15) {<\/p>\n<p>if(aSize&lt;maxAgentSize) aSize+=increaseSize; \/\/increase size of agent<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>\/\/explode if too fat&#8230;<\/p>\n<p>if(aSize&gt;8){<\/p>\n<p>\/\/ rupture();<\/p>\n<p>}else{<\/p>\n<p>ruptured = false;<\/p>\n<p>}<\/p>\n<p>\/\/pull back to the threshold<\/p>\n<p>pushPullToData(0.1);<\/p>\n<p>}<\/p>\n<p>void attract (Vec3D v, float d){<\/p>\n<p>acc.interpolateToSelf(v,(aAttract\/d));<\/p>\n<p>}<\/p>\n<p>void align(Vec3D v, float d){<\/p>\n<p>acc.interpolateToSelf(v,aAlign);<\/p>\n<p>}<\/p>\n<p>void repel (Vec3D v, float d){<\/p>\n<p>v.invert();<\/p>\n<p>acc.interpolateToSelf(v,(aRepel\/d));<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/random tree search and respawn<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void searchTrees(){<\/p>\n<p>if(loc.z&lt;10){<\/p>\n<p>Vec3D searchDir = new Vec3D(random(-1,1),random(-1,1),random(0));<\/p>\n<p>vel.set(vel.x,vel.y,vel.z\/10);<\/p>\n<p>acc.interpolateToSelf(searchDir,0.1);<\/p>\n<p>}else{<\/p>\n<p>vel.addSelf(new Vec3D(0,0,-0.5));<\/p>\n<p>pushPullToData(0.1);<\/p>\n<p>}<\/p>\n<p>\/\/if(loc.z&lt;10)vel.set(vel.x,vel.y,vel.z\/10);<\/p>\n<p>\/\/check for nearby trees<\/p>\n<p>for (TreeAttractor t:forest){<\/p>\n<p>if(t.volume&gt;0){<\/p>\n<p>if(loc.distanceTo(t.loc)&lt;distToTree){<\/p>\n<p>parent = t;<\/p>\n<p>respawn(t);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>void respawn(TreeAttractor t){<\/p>\n<p>for (int i=0;i&lt;20;i++){<\/p>\n<p>\/\/ Vec3D loc = new Vec3D(random(0,gW*gRes),random(0,gH*gRes),0);<\/p>\n<p>Vec3D loc = new Vec3D(random(-spawnSizeXY,spawnSizeXY),random(-spawnSizeXY,spawnSizeXY),0);<\/p>\n<p>loc.addSelf(t.loc);<\/p>\n<p>Vec3D vel = new Vec3D(0,0,1);<\/p>\n<p>Agent a = new Agent(loc,vel,t);<\/p>\n<p>addList.add(a);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Spawning\/rupture functions<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void rupture(){<\/p>\n<p>if(!ruptured){<\/p>\n<p>for (int i=0;i&lt;10;i++){<\/p>\n<p>\/\/ Vec3D sVel = new Vec3D(random(-1,1),random(-1,1),random(-1,1));<\/p>\n<p>Vec3D sVel = vel.cross(new Vec3D(0,0,1));<\/p>\n<p>sVel.rotateZ(random(-0.8,0.8));<\/p>\n<p>SapMonster a = new SapMonster(loc.add(sVel),sVel,this);<\/p>\n<p>sapPop.add(a);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>ruptured = true;<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Voxel and volume brush functions<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void volBrushLocation(){<\/p>\n<p>brush.setSize(aSize);<\/p>\n<p>float aX = constrain(loc.x,0,SCALE.x);<\/p>\n<p>aX = map(aX,0,SCALE.x,0,DX);<\/p>\n<p>float aY = constrain(loc.y,0,SCALE.y);<\/p>\n<p>aY = map(aY,0,SCALE.y,0,DY);<\/p>\n<p>float aZ = constrain(loc.z,0,SCALE.z);<\/p>\n<p>aZ = map(aZ,0,SCALE.z,0,DZ);<\/p>\n<p>brush.drawAtGridPos(aX,aY,aZ,density);<\/p>\n<p>parent.volume-=0.1;<\/p>\n<p>}<\/p>\n<p>void getGridPos(){<\/p>\n<p>aX = constrain(loc.x,0,SCALE.x);<\/p>\n<p>aX = map(aX,0,SCALE.x,0,DX);<\/p>\n<p>aY = constrain(loc.y,0,SCALE.y);<\/p>\n<p>aY = map(aY,0,SCALE.y,0,DY);<\/p>\n<p>aZ = constrain(loc.z,0,SCALE.z);<\/p>\n<p>aZ = map(aZ,0,SCALE.z,0,DZ);<\/p>\n<p>}<\/p>\n<p>void pushPullToData(float t){<\/p>\n<p>float bestThreshDiff = 100;<\/p>\n<p>Vec3D bestThreshPt = new Vec3D(0,0,0);<\/p>\n<p>\/\/iterate over neighbouring grid pos<\/p>\n<p>for (int i =-5;i&lt;=5;i++){<\/p>\n<p>for (int j =-5;j&lt;=5;j++){<\/p>\n<p>for (int k =-5; k&lt;=5;k++){<\/p>\n<p>\/\/if the value of this noisepoints better than the others, then update variables<\/p>\n<p>\/\/scale val by distance<\/p>\n<p>Vec3D vec = new Vec3D(i,j,k);<\/p>\n<p>if((aX+i)&gt;=0&amp;&amp;(aX+i)&lt;DX&amp;&amp;(aY+j)&gt;=0&amp;&amp;(aY+j)&lt;DY&amp;&amp;(aZ+k)&gt;=0&amp;&amp;(aZ+k)&lt;DZ){<\/p>\n<p>float val = volume.getVoxelAt(int(aX+i),int(aY+j),int(aZ+k));<\/p>\n<p>\/\/only use pts within field of view<\/p>\n<p>float angleDiff = vel.angleBetween(vec,true);<\/p>\n<p>angleDiff = map(angleDiff,0,PI*2,0,1);<\/p>\n<p>if(angleDiff&lt;0.5){<\/p>\n<p>float threshVal = abs(val-t);<\/p>\n<p>if(threshVal &lt;bestThreshDiff) bestThreshDiff=threshVal;<\/p>\n<p>\/\/float threshVal = val;<\/p>\n<p>vec.scaleSelf(1-((threshVal)*(1-angleDiff)));<\/p>\n<p>bestThreshPt.addSelf(vec);<\/p>\n<p>if(threshVal&lt;bestThreshDiff)bestThreshDiff=threshVal;<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>if(bestThreshDiff&lt;0.01){<\/p>\n<p>\/\/attract to threshold<\/p>\n<p>bestThreshPt.scaleSelf(0.05);<\/p>\n<p>acc.addSelf(bestThreshPt);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Functions for managing trails and rendering the agent.<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void update(){<\/p>\n<p>\/\/move the agent<\/p>\n<p>acc.limit(aAccel);<\/p>\n<p>vel.addSelf(acc);<\/p>\n<p>vel.limit(agentSpeed);<\/p>\n<p>loc.addSelf(vel);<\/p>\n<p>\/\/update the trail geom every 5 moves<\/p>\n<p>if(dropNum%dropSpacing==0){<\/p>\n<p>if(trail.size()&lt;trailLength){<\/p>\n<p>trail.add(new Vec3D(loc.x, loc.y, loc.z));<\/p>\n<p>}else{<\/p>\n<p>trail.remove(0);<\/p>\n<p>}<\/p>\n<p>dropNum=0;<\/p>\n<p>}<\/p>\n<p>dropNum++;<\/p>\n<p>}<\/p>\n<p>void render(){<\/p>\n<p>\/\/render agent trail as lines<\/p>\n<p>Vec3D ls = null;<\/p>\n<p>stroke(255);<\/p>\n<p>for (Vec3D l : trail){<\/p>\n<p>if(ls !=null){<\/p>\n<p>line (l.x,l.y,l.z,ls.x,ls.y,ls.z);<\/p>\n<p>}<\/p>\n<p>ls = l;<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>void renderPts(){<\/p>\n<p>\/\/render agent trail as lines<\/p>\n<p>for (Vec3D l : trail){<\/p>\n<p>point (l.x,l.y,l.z);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<ul>\n<li>\/\/\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013Controller\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013\/\/<\/li>\n<\/ul>\n<p>void setupP5 (){<\/p>\n<p>controlP5 = new ControlP5(this);<\/p>\n<p>controlP5.setAutoDraw(false);<\/p>\n<p>controlWindow = controlP5.addControlWindow(&#8220;controlP5window&#8221;,100,100,400,300);<\/p>\n<p>controlWindow.hideCoordinates();<\/p>\n<p>Controller mySlider1 = controlP5.addSlider(&#8220;agentSpeed&#8221;,0,3.5).linebreak();<\/p>\n<p>mySlider1.setWindow(controlWindow);<\/p>\n<p>Controller mySlider2 = controlP5.addSlider(&#8220;aAttract&#8221;,0,5.00).linebreak();<\/p>\n<p>mySlider2.setWindow(controlWindow);<\/p>\n<p>Controller mySlider3 = controlP5.addSlider(&#8220;aAlign&#8221;,0,0.10).linebreak();<\/p>\n<p>mySlider3.setWindow(controlWindow);<\/p>\n<p>Controller mySlider4 = controlP5.addSlider(&#8220;aRepel&#8221;,0,5.00).linebreak();<\/p>\n<p>mySlider4.setWindow(controlWindow);<\/p>\n<p>Controller mySlider8 = controlP5.addSlider(&#8220;aAccel&#8221;,0,0.100).linebreak();<\/p>\n<p>mySlider8.setWindow(controlWindow);<\/p>\n<p>Controller mySlider5 =controlP5.addSlider(&#8220;dropSpacing&#8221;,1,20).linebreak();<\/p>\n<p>mySlider5.setWindow(controlWindow);<\/p>\n<p>Controller mySlider6 =controlP5.addSlider(&#8220;trailLength&#8221;,1,200).linebreak();<\/p>\n<p>mySlider6.setWindow(controlWindow);<\/p>\n<p>Controller mySlider7 =controlP5.addSlider(&#8220;spawnSizeXY&#8221;,10,500).linebreak();<\/p>\n<p>mySlider7.setWindow(controlWindow);<\/p>\n<p>Controller mySlider9 =controlP5.addSlider(&#8220;maxAgentSize&#8221;,5,30).linebreak();<\/p>\n<p>mySlider9.setWindow(controlWindow);<\/p>\n<p>Controller mySlider10 =controlP5.addSlider(&#8220;increaseSize&#8221;,0.1,0.6).linebreak();<\/p>\n<p>mySlider10.setWindow(controlWindow);<\/p>\n<p>controlWindow.setTitle(&#8220;Spring GUI&#8221;);<\/p>\n<p>}<\/p>\n<ul>\n<li>\/\/\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013Initialisation\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013\/\/<\/li>\n<li><\/li>\n<\/ul>\n<p>\/\/ this is the function that creates all of the agents that fly through the<\/p>\n<p>\/\/ noisefield. So this is where you control the agents initial location<\/p>\n<p>\/\/ and also their initial velocity.<\/p>\n<p>void spawn(){<\/p>\n<p>agentPop = new ArrayList();<\/p>\n<p>TreeAttractor p = forest.get(firstTree);<\/p>\n<p>for (int i=0;i&lt;numAgents;i++){<\/p>\n<p>\/\/ Vec3D loc = new Vec3D(random(0,gW*gRes),random(0,gH*gRes),0);<\/p>\n<p>Vec3D loc = new Vec3D(random(spawnSizeXY\/2,spawnSizeXY*1.5),random(spawnSizeXY\/2,spawnSizeXY*1.5),0);<\/p>\n<p>loc.addSelf(p.loc);<\/p>\n<p>Vec3D vel = new Vec3D(0,0,1);<\/p>\n<p>Agent a = new Agent(loc,vel,p);<\/p>\n<p>agentPop.add(a);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>\/\/a couple of voxel functions<\/p>\n<p>void drawVox(){<\/p>\n<p>for (int i=0;i&lt;DX;i+=r){<\/p>\n<p>for (int j =0;j&lt;DY;j+=r){<\/p>\n<p>for (int k=0;k&lt;DZ;k+=r){<\/p>\n<p>\/\/make a point at the current coordinate,<\/p>\n<p>\/\/use the value of the noise at that point<\/p>\n<p>\/\/as the points colour.<\/p>\n<p>float v = volume.getVoxelAt(i,j,k)*200;<\/p>\n<p>if(v&gt;1){<\/p>\n<p>stroke(v);<\/p>\n<p>line(i*sX,j*sY,k*sZ,i*sX,j*sY,k*sZ+1);<\/p>\n<p>}else if(v&lt;-1){<\/p>\n<p>stroke(abs(v),0,0);<\/p>\n<p>line(i*sX,j*sY,k*sZ,i*sX+2,j*sY,k*sZ);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>public void GsaveData(VolumetricSpaceArray v,String fn) {<\/p>\n<p>print(&#8220;saving volume data&#8230;&#8221;);<\/p>\n<p>int c=0;<\/p>\n<p>int tot = v.getData().length;<\/p>\n<p>try {<\/p>\n<p>BufferedOutputStream ds = new BufferedOutputStream(new FileOutputStream(fn));<\/p>\n<p>\/\/ ds.writeInt(volumeData.length);<\/p>\n<p>for (float element : v.getData()) {<\/p>\n<p>if(element&lt;0)element=0;<\/p>\n<p>ds.write((int)(element*100));<\/p>\n<p>}<\/p>\n<p>ds.flush();<\/p>\n<p>ds.close();<\/p>\n<p>} catch (IOException e) {<\/p>\n<p>e.printStackTrace();<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>void importLandscape() {<\/p>\n<p>forest = new ArrayList&lt;TreeAttractor&gt;();<\/p>\n<p>\/\/load text<\/p>\n<p>String[] txtLines = loadStrings(&#8220;trees.txt&#8221;);<\/p>\n<p>\/\/splits strand points<\/p>\n<p>String[] arrCoords = split(txtLines[0], &#8216;_&#8217;);<\/p>\n<p>for (int j = 0; j &lt; arrCoords.length; ++j) {<\/p>\n<p>\/\/separates coords<\/p>\n<p>String[] arrToks = split(arrCoords[j], &#8216;,&#8217;);<\/p>\n<p>float xx = Float.valueOf(arrToks[0]);<\/p>\n<p>float yy = Float.valueOf(arrToks[1]);<\/p>\n<p>float zz = Float.valueOf(arrToks[2]);<\/p>\n<p>\/\/create node<\/p>\n<p>Vec3D tmpPt = new Vec3D(xx, yy, 0);<\/p>\n<p>TreeAttractor tree = new TreeAttractor(tmpPt);<\/p>\n<p>forest.add(tree);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<ul>\n<li>\/\/\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013Point\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013\/\/<\/li>\n<\/ul>\n<p>class TreeAttractor {<\/p>\n<p>Vec3D loc;<\/p>\n<p>float volume;<\/p>\n<p>TreeAttractor(Vec3D LOC){<\/p>\n<p>loc = LOC;<\/p>\n<p>volume = 1000;<\/p>\n<p>}<\/p>\n<p>void render(){<\/p>\n<p>point(loc.x,loc.y,loc.z);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<ul>\n<li>\/\/\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013Sap Monster \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2013\/\/<\/li>\n<\/ul>\n<p>\/\/simple agent class to interact with the data<\/p>\n<p>\/\/field and other agents<\/p>\n<p>class SapMonster {<\/p>\n<p>Vec3D loc,vel,acc;<\/p>\n<p>float aSize;<\/p>\n<p>float age;<\/p>\n<p>boolean alive;<\/p>\n<p>Agent a;<\/p>\n<p>SapMonster(Vec3D _loc, Vec3D _vel, Agent _a){<\/p>\n<p>loc = _loc;<\/p>\n<p>acc = new Vec3D(0,0,0);<\/p>\n<p>vel = _vel;<\/p>\n<p>aSize =2;<\/p>\n<p>a = _a;<\/p>\n<p>age = 0;<\/p>\n<p>alive = true;<\/p>\n<p>}<\/p>\n<p>void run(){<\/p>\n<p>searchAgents();<\/p>\n<p>updatePos();<\/p>\n<p>volBrushLocation();<\/p>\n<p>render();<\/p>\n<p>if(age&gt;5) alive= false;<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Basic Lace Function. Draws an arc with the agent.<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void updatePos(){<\/p>\n<p>acc.interpolateToSelf(a.vel,0.1);<\/p>\n<p>acc.limit(0.2);<\/p>\n<p>vel.addSelf(acc);<\/p>\n<p>vel.limit(1);<\/p>\n<p>loc.addSelf(vel);<\/p>\n<p>age+=0.1;<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Global Attraction functions<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void searchAgents(){<\/p>\n<p>\/\/reset accel<\/p>\n<p>for (SapMonster s:sapPop){<\/p>\n<p>\/\/get essential variables<\/p>\n<p>Vec3D diff = s.loc.sub(loc.copy());<\/p>\n<p>float d = diff.magnitude();<\/p>\n<p>if(d&gt;30){<\/p>\n<p>attract(diff.copy(),d); \/\/attract to neighbour<\/p>\n<p>}else if (d&gt;1 &amp;&amp;d&lt;30){<\/p>\n<p>repel(diff.copy(),d); \/\/repel<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>void attract (Vec3D v, float d){<\/p>\n<p>\/\/ v.normalizeTo(0.01\/d);<\/p>\n<p>acc.interpolateToSelf(v,0.01\/d);<\/p>\n<p>}<\/p>\n<p>void repel (Vec3D v, float d){<\/p>\n<p>v.invert();<\/p>\n<p>\/\/v.normalizeTo(0.01\/d);<\/p>\n<p>acc.interpolateToSelf(v,1\/d);<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Voxel and volume brush functions<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void volBrushLocation(){<\/p>\n<p>brush.setSize(aSize);<\/p>\n<p>float aX = constrain(loc.x,0,SCALE.x);<\/p>\n<p>aX = map(aX,0,SCALE.x,0,DX);<\/p>\n<p>float aY = constrain(loc.y,0,SCALE.y);<\/p>\n<p>aY = map(aY,0,SCALE.y,0,DY);<\/p>\n<p>float aZ = constrain(loc.z,0,SCALE.z);<\/p>\n<p>aZ = map(aZ,0,SCALE.z,0,DZ);<\/p>\n<p>brush.drawAtGridPos(aX,aY,aZ,-density);<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Functions for managing trails and rendering the agent.<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void render(){<\/p>\n<p>point (loc.x,loc.y,loc.z);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\/* * Copyright (c) 2012 Gwyllim Jahn * http:\/\/scripts.crida.net\/gh * Developed By Gwyllim Jahn, Kathryn McKenzie and Sarah Papadopoullos * during the 2012 RMIT nCertainties studio. * * This code makes extensive use of several freely distributed * processing libraries \u2013 thankyou especially to toxi. *This code is free software; you can redistribute it and\/or [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":20,"menu_order":0,"comment_status":"closed","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-705","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages\/705","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/comments?post=705"}],"version-history":[{"count":7,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages\/705\/revisions"}],"predecessor-version":[{"id":1015,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages\/705\/revisions\/1015"}],"up":[{"embeddable":true,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages\/20"}],"wp:attachment":[{"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/media?parent=705"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}