Gallery details
Culebra MultiBehavior Connectivity System – OcTree Optimized
Download the App – prolebra.0.9Beta snippet Test
A multi behavior octree optimized multi agent system built in Processing 3.0 inspired by flocking and Silkworm Behaviors.
PROCESSING 3.0 SKETCH CODE
MAIN
import java.util.List; import toxi.geom.*; import toxi.geom.PointOctree; import toxi.color.*; import controlP5.*; import peasy.*; Tracker a; ControlP5 cp5; Culebra_UI cgui; Path tempPath; PVector locStart; PVector triggerLoc = new PVector(0, 0, 0); boolean simulate, spawnEdge, addNew, D2; boolean drawPathTargets, toggleUI, drawMovement, mathBehavior, genRandom, triggerSeekers, drawBoundary, drawConn, createOctree; boolean toggleColor = true; boolean masterBehavior_A = true; boolean masterBehavior_B, masterBehavior_C, masterBehavior_D, masterBehavior_E, subBehavior_AA, subBehavior_AB; boolean drawPaths = false; boolean SpawnEdge = true; boolean Dimension = true; boolean enablePathTrack = true; boolean showOctree = true; int triggerCount = 0; int agentCount = 500; int resetAmount = 0; int camToggle = 0; int pathCount = 15; int nWidth = 1920; int nDepth = 1080; int nHeight = 1000; float WanderRadius, WanderDist, WanderTheta, WanderRotTrigger, MaxChildren; float PathRad, ScalarProjectDist, PathThresh; float InitSpeed, MaxSpeed, MaxForce, MaxSep; float AgentCount; float seekerTrail, childSeekerTrail; float HeadWidth, StrokeWidth, Transparency; float stepCount = 0; float sepTrigger = 0.0f; ArrayList<PVector>childSpawners; ArrayList childSpawnType; ArrayList<Path> pathList; List<Tracker> agentList; java.util.List occTreeList; List<Vec3D>vec3DList; VisibleOctree octree; Button btypeA, btypeAA, btypeAB, btypeB, btypeC, btypeD, btypeE; PeasyCam cam; CameraState state; //---------------------------------------Settings-------------------------------------------- void settings() { size(1920, 1080, P3D); smooth(); } //---------------------------------------Setup----------------------------------------------- void setup() { background(0); this.octree = new VisibleOctree(new Vec3D(0, 0, 0), nWidth); this.octree.setTreeAutoReduction(true); this.agentList = new ArrayList<Tracker>(); this.childSpawners = new ArrayList<PVector>(); this.childSpawnType = new ArrayList(); this.pathList = new ArrayList<Path>(); if (!this.D2 && this.camToggle < 1) { this.camToggle ++; this.cam = new PeasyCam(this, 1500); this.cam.setMinimumDistance(100); this.cam.setMaximumDistance(10000); this.cam.lookAt(this.nWidth/2, this.nDepth/2, this.nHeight/2); this.cam.setSuppressRollRotationMode(); } if (D2) { this.cam.reset(); this.cam.setMinimumDistance(100); this.cam.setMaximumDistance(10000); this.cam.lookAt(this.nWidth/2, this.nDepth/2, 0); this.cam.setDistance(1000); // distance from looked-at point this.cam.setSuppressRollRotationMode(); } simulate = true; if (this.resetAmount == 0) { this.cgui = new Culebra_UI(); this.cgui.run(this); } for (int pth = 0; pth < this.pathCount; pth++) { newPath(); } for (int i = 0; i < this.agentCount; i ++) { PVector speed; if (this.D2) { if (this.spawnEdge) { locStart = new PVector(0, random(height), 0); speed = new PVector(1, 0, 0); } else { locStart = new PVector(random(width), random(height), 0); speed = new PVector(random(-1, 1), random(-1, 1), 0); } //this.octree.addPoint(new Vec3D(locStart.x,locStart.y,locStart.z)); this.a = new Tracker(locStart, speed, true, "parent", "main"); } else { if (this.spawnEdge) { locStart = new PVector(random(width), random(height), 0); speed = new PVector(random(-1, 1), random(-1, 1), random(0, 2)); } else { locStart = new PVector(random(width), random(height), random(0, nHeight)); speed = new PVector(random(-1, 1), random(-1, 1), random(-1, 1)); } //this.octree.addPoint(new Vec3D(locStart.x,locStart.y,locStart.z)); this.a = new Tracker(locStart, speed, true, "parent", "main"); } this.agentList.add(this.a); } } //---------------------------------------Draw------------------------------------------------ void draw() { background(0); this.sepTrigger = this.cgui.msep.getValue(); if (this.createOctree || this.masterBehavior_E || this.sepTrigger > 0) { this.createOctree = true; this.octree.empty(); this.vec3DList = new ArrayList<Vec3D>(); //--Sets the octree pts------------------------------------------------------------------ for (Tracker ag : agentList) { this.vec3DList.add(new Vec3D(ag.loc.x, ag.loc.y, ag.loc.z)); } this.octree.addAll(vec3DList); } this.D2 = this.cgui.d.getState(); if (!this.D2 && this.drawBoundary) { drawExtents(); } this.spawnEdge = this.cgui.se.getState(); this.agentCount = (int)this.cgui.ac.getValue(); for (Path pths : pathList) { if (this.drawPaths) { pths.display(); } pths.dim = this.cgui.d.getState(); pths.radius = this.cgui.pr.getValue(); } //--Agents------------------------------------------------------------------------------- for (Tracker ag : agentList) { if (ag.type == "parent") { ag.wanderD = this.cgui.wd.getValue(); ag.wanderR = this.cgui.wr.getValue(); ag.wanderT = this.cgui.wt.getValue(); ag.wanderTVal = this.cgui.wrt.getValue(); ag.headWidth = this.cgui.hw.getValue(); ag.strokeWidth = this.cgui.stw.getValue(); ag.tranparency = this.cgui.t.getValue(); ag.seekerMT = (int)this.cgui.st.getValue(); ag.maxforce = this.cgui.mf.getValue(); ag.max = this.cgui.ms.getValue(); ag.amp = this.cgui.sd.getValue(); ag.vel = this.cgui.is.getValue(); ag.maxDist = this.cgui.pt.getValue(); ag.r = this.cgui.msep.getValue(); ag.maxChildren = (int)this.cgui.mc.getValue(); ag.dim = this.cgui.d.getState(); ag.randomize = this.genRandom; ag.wandertheta = 0.0f; ag.av = this.cgui.f_av.getValue(); ag.cv = this.cgui.f_cv.getValue(); ag.sv = this.cgui.f_sv.getValue(); ag.searchRad = this.cgui.f_sR.getValue(); ag.creeperCollection = this.agentList; ag.run(); } else { ag.wanderD = this.cgui.c_wd.getValue(); ag.wanderR = this.cgui.c_wr.getValue(); ag.wanderT = this.cgui.c_wt.getValue(); ag.wanderTVal = this.cgui.c_wrt.getValue(); ag.headWidth = this.cgui.c_hw.getValue(); ag.strokeWidth = this.cgui.c_stw.getValue(); ag.tranparency = this.cgui.c_t.getValue(); ag.seekerChildMT = (int)this.cgui.c_ct.getValue(); ag.maxforce = this.cgui.c_mf.getValue(); ag.max = this.cgui.c_ms.getValue(); ag.amp = this.cgui.c_sd.getValue(); ag.vel = this.cgui.c_is.getValue(); ag.maxDist = this.cgui.c_pt.getValue(); //ag.r = this.cgui.c_msep.getValue(); ag.maxChildren = 0; ag.dim = this.cgui.d.getState(); ag.randomize = this.genRandom; ag.wandertheta = 0.0f; ag.av = this.cgui.f_av.getValue(); ag.cv = this.cgui.f_cv.getValue(); ag.sv = this.cgui.f_sv.getValue(); ag.searchRad = this.cgui.f_sR.getValue(); ag.creeperCollection = this.agentList; ag.run(); } } if (this.createOctree) { if (this.showOctree) this.octree.draw(); } //--CreateBabies--------------------------------------------------------------------------- if (this.childSpawners.size() > 0) { newDude(); this.childSpawners = new ArrayList<PVector>(); this.childSpawnType = new ArrayList(); } stepCount++; if (this.D2) { surface.setSize(this.nWidth, this.nDepth); } this.cgui.createGui(); } //---------------------------------------Create Static Paths--------------------------------- void newPath() { if (this.D2) { this.tempPath = new Path(); this.tempPath.addPoint(random(30, 300), random(height/4, height), 0); this.tempPath.addPoint(random(101, width/2), random(0, height), 0); this.tempPath.addPoint(random(width/2, width), random(0, height), 0); this.tempPath.addPoint(random(width-100, width), height/2, 0); } else { this.tempPath = new Path(); this.tempPath.addPoint(random(0, 300), random(0, height), random(0, this.nHeight)); this.tempPath.addPoint(random(0, width/2), random(0, height), random(0, this.nHeight)); this.tempPath.addPoint(random(0, width), random(0, height), random(0, this.nHeight)); this.tempPath.addPoint(random(0, width), 0, random(0, this.nHeight)); } this.pathList.add(this.tempPath); } //---------------------------------------Keyboard Inputs------------------------------------- void keyPressed() { if (key == 'r') { this.resetAmount ++; this.triggerCount = 0; setup(); } if (key == 's') this.simulate = !this.simulate; if (key == 'w') this.newPath(); if (key == 'q') this.drawPathTargets = !this.drawPathTargets; if (key == 'p') this.drawPaths = !this.drawPaths; if (key == 't') this.toggleUI = !this.toggleUI; if (key == 'm') this.mathBehavior = !this.mathBehavior; if (key == 'n') this.genRandom = !this.genRandom; if (key == 'd') this.drawMovement = !this.drawMovement; if (key == 'P') this.enablePathTrack = !this.enablePathTrack; if (key == 'b') this.triggerSeekers = !this.triggerSeekers; if (key == 'c') this.toggleColor = !this.toggleColor; if (key == 'i') saveFrame("img-######.png"); if (key == 'v') this.drawBoundary = !this.drawBoundary; if (key=='o') this.showOctree=!this.showOctree; if (key=='z') this.createOctree =!this.createOctree; if (key=='1') this.drawConn=!this.drawConn; } //---------------------------------------Children Creation----------------------------------- void newDude() { int babyCount = 0; for (PVector px : this.childSpawners) { PVector speed; if (this.spawnEdge) { speed = new PVector(1, 0, 0); } else { speed = new PVector(random(-1, 1), random(-1, 1), 0); } if ((int)this.childSpawnType.get(babyCount) % 2 == 0) { this.agentList.add(new Tracker(new PVector(px.x, px.y, px.z), speed, false, "child", "w_a")); } else { this.agentList.add(new Tracker(new PVector(px.x, px.y, px.z), speed, false, "child", "w_b")); } babyCount++; } } //---------------------------------------Draw Bounds----------------------------------------- void drawExtents() { pushStyle(); pushMatrix(); strokeWeight(.5); stroke(200); noFill(); translate(this.nWidth/2, this.nDepth/2, this.nHeight/2); box(this.nWidth, this.nDepth, this.nHeight); popMatrix(); popStyle(); } //---------------------------------------Behaviors------------------------------------------ void Beh_A(boolean resetFlag) { if (resetFlag) { this.masterBehavior_A = !this.masterBehavior_A; } } void Beh_B(boolean resetFlag) { if (resetFlag) { this.masterBehavior_B = !this.masterBehavior_B; } } void Beh_C(boolean resetFlag) { if (resetFlag) { this.masterBehavior_C = !this.masterBehavior_C; } } void Beh_D(boolean resetFlag) { if (resetFlag) { this.masterBehavior_D = !this.masterBehavior_D; } } void Beh_E(boolean resetFlag) { if (resetFlag) { this.masterBehavior_E = !this.masterBehavior_E; } } void Beh_AA(boolean resetFlag) { if (resetFlag) { this.subBehavior_AA = !this.subBehavior_AA; } } void Beh_AB(boolean resetFlag) { if (resetFlag) { this.subBehavior_AB = !this.subBehavior_AB; } } Update
UI
class Culebra_UI { PApplet parent; ControlP5 cp5; int abc = 100; Slider pr, sd, pt, wr, wd, wrt, wt, mc, is, ms, mf, msep, ac, st, sct, hw, stw, t; Slider c_sd, c_pt, c_wr, c_wd, c_wrt, c_wt, c_is, c_ms, c_mf, c_msep, c_ct, c_mvr, c_mxvr, c_mvA, c_MvA, c_hw, c_t, c_stw; Slider f_sR, f_av, f_sv, f_cv; Button cbutt, cbut; Toggle se, d, t10; List<Slider> sliderList = new ArrayList<Slider>(); boolean created = false; public Culebra_UI () { } public void run(PApplet _parent) { this.parent = _parent; this.cp5 = new ControlP5(parent); if (!D2) { this.cp5.setAutoDraw(false); } else { this.cp5.setAutoDraw(true); } this.cp5.setColorForeground(color(0, 255, 0)); this.cp5.setColorValueLabel(color(255, 255, 255)); this.cp5.setBackground(color(0, 0, 0)); this.cp5.setColorActive(color(0, 255, 0)); this.cp5.setColorBackground(color(50, 50, 50)); this.pr = cp5.addSlider("PathRad").plugTo(parent).setRange(0, 100).setPosition(10, 10).setValue(28.0).setDecimalPrecision(2).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); this.sd = cp5.addSlider("ScalarProjectDist").plugTo(parent).plugTo(parent).setRange(0.00, 100.00).setPosition(10, 22).setValue(100).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.pt = cp5.addSlider("PathTresh").plugTo(parent).setRange(0.00, 1500.00).setPosition(10, 34).setValue(1000.0).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.wr = cp5.addSlider("WanderRadius").plugTo(parent).setRange(0.00, 500.00).setPosition(10, 46).setValue(10).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.wd = cp5.addSlider("WanderDist").plugTo(parent).setRange(0.00, 100.00).setPosition(10, 58).setValue(20).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.wrt = cp5.addSlider("WanderRotTrigger").plugTo(parent).setRange(0.00, 100.00).setPosition(10, 70).setValue(6).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.wt = cp5.addSlider("WanderTheta").plugTo(parent).setRange(0.0, 100.00).setPosition(10, 82).setValue(0.6).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.mc = cp5.addSlider("MaxChildren").plugTo(parent).plugTo(parent).setRange(0.00, 20.00).setPosition(10, 94).setValue(4).setDecimalPrecision(0).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.is = cp5.addSlider("InitSpeed").plugTo(parent).setRange(0.00, 10.00).setPosition(10, 106).setValue(2.0).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); this.ms = cp5.addSlider("MaxSpeed").plugTo(parent).setRange(0.00, 10.00).setPosition(10, 118).setValue(3.0).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); this.mf = cp5.addSlider("MaxForce").plugTo(parent).setRange(0.00, 2.00).setPosition(10, 130).setValue(0.16).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); this.msep = cp5.addSlider("MaxSep").plugTo(parent).plugTo(parent).setRange(0.00, 20.00).setPosition(10, 142).setValue(0.0).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.ac = cp5.addSlider("AgentCount").plugTo(parent).setRange(0.00, 2500.00).setPosition(10, 154).setValue(500).setDecimalPrecision(0).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); this.se = cp5.addToggle("SpawnEdge").plugTo(parent).setPosition(10, 166).setSize(50, 10).setValue(false).setMode(ControlP5.SWITCH).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); this.d = cp5.addToggle("Dimension").plugTo(parent).setPosition(10, 190).setSize(50, 10).setValue(false).setMode(ControlP5.SWITCH).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); Button sbutt = cp5.addButton("---TRACKERS---").plugTo(parent).setPosition(10, 220).setSize(100, 5); sbutt.setColorActive(color(0, 255, 0)); sbutt.setColorBackground(color(255, 0, 0)); this.st = cp5.addSlider("seekerTrail").plugTo(parent).setRange(0.00, 5000.00).setPosition(10, 230).setValue(5000).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); Button wbutt = cp5.addButton("---SEEKERS---").plugTo(parent).setPosition(10, 244).setSize(100, 5); wbutt.setColorActive(color(0, 255, 0)); wbutt.setColorBackground(color(255, 0, 0)); this.sct = cp5.addSlider("childSeekerTrail").plugTo(parent).setRange(0.00, 5000.00).setPosition(10, 254).setValue(5000.0).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); Button vbutt = cp5.addButton("---VIZ---").plugTo(parent).setPosition(10, 268).setSize(100, 5); vbutt.setColorActive(color(0, 255, 0)); vbutt.setColorBackground(color(255, 0, 0)); this.hw = cp5.addSlider("HeadWidth").plugTo(parent).setRange(0.00f, 8.0f).setPosition(10, 278).setValue(0.0f) .setDecimalPrecision(2).setSize(50, 10); this.stw = cp5.addSlider("StrokeWidth").plugTo(parent).setRange(0.00f, 10).setPosition(10, 290).setValue(1.5f) .setDecimalPrecision(2).setSize(50, 10); this.t = cp5.addSlider("Transparency").plugTo(parent).setRange(0.00f, 255).setPosition(10, 302) .setValue(255.0f).setDecimalPrecision(2).setSize(50, 10); this.cbut = cp5.addButton("---BABIES---").plugTo(parent).setPosition(10, 316).setSize(100, 5); this.cbut.setColorActive(color(0, 255, 0)); this.cbut.setColorBackground(color(255, 0, 0)); //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- this.c_sd = cp5.addSlider("c_ScalarProjectDist").plugTo(parent).plugTo(parent).setRange(0.00, 100.00).setPosition(10, 326).setValue(100).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; sliderList.add(this.c_sd); this.c_pt = cp5.addSlider("c_PathTresh").plugTo(parent).setRange(0.00, 1500.00).setPosition(10, 338).setValue(1000).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; sliderList.add(this.c_pt); this.c_wr = cp5.addSlider("c_WanderRad").plugTo(parent).setRange(0.00, 100.00).setPosition(10, 350).setValue(10).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; sliderList.add(this.c_wr); this.c_wd = cp5.addSlider("c_WanderDist").plugTo(parent).setRange(0.00, 100.00).setPosition(10, 362).setValue(20).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; sliderList.add(this.c_wd); this.c_wrt = cp5.addSlider("c_WanderRotTrigger").plugTo(parent).setRange(0.00, 100.00).setPosition(10, 374).setValue(6).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; sliderList.add(this.c_wrt); this.c_wt = cp5.addSlider("c_WanderTheta").plugTo(parent).setRange(0.0, 100.00).setPosition(10, 386).setValue(0.6).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; sliderList.add(this.c_wt); this.c_is = cp5.addSlider("c_InitSpeed").plugTo(parent).setRange(0.00, 10.00).setPosition(10, 398).setValue(2.0).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); sliderList.add(this.c_is); this.c_ms = cp5.addSlider("c_MaxSpeed").plugTo(parent).setRange(0.00, 10.00).setPosition(10, 410).setValue(3.0).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); sliderList.add(this.c_ms); this.c_mf = cp5.addSlider("c_MaxForce").plugTo(parent).setRange(0.00, 2.00).setPosition(10, 422).setValue(0.16).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); sliderList.add(this.c_mf); this.c_ct = cp5.addSlider("c_Child_TrailFO").plugTo(parent).setRange(0.00, 5000.00).setPosition(10, 434).setValue(5000).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)); sliderList.add(this.c_ct); this.cbutt = cp5.addButton("---Child-VIZ---").plugTo(parent).setPosition(10, 448).setSize(100, 5); this.cbutt.setColorActive(color(0, 255, 0)); this.cbutt.setColorBackground(color(255, 0, 0)); this.c_hw = cp5.addSlider("c_HeadWidth").plugTo(parent).setRange(0.00f, 8.0f).setPosition(10, 460).setValue(0.0f) .setDecimalPrecision(2).setSize(50, 10); sliderList.add(this.c_hw); this.c_stw = cp5.addSlider("c_StrokeWidth").plugTo(parent).setRange(0.00f, 10).setPosition(10, 472).setValue(1.1f) .setDecimalPrecision(2).setSize(50, 10); sliderList.add(this.c_stw); this.c_t = cp5.addSlider("c_Transparency").plugTo(parent).setRange(0.00f, 255).setPosition(10, 484) .setValue(255.0f).setDecimalPrecision(2).setSize(50, 10); sliderList.add(this.c_t); this.f_sR = cp5.addSlider("searchRadius").plugTo(parent).plugTo(parent).setRange(0.00, 300.00).setPosition(10, 500).setValue(30).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.f_av = cp5.addSlider("alignValue").plugTo(parent).plugTo(parent).setRange(0.00, 2.00).setPosition(10, 512).setValue(0.025).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.f_sv = cp5.addSlider("sepValue").plugTo(parent).plugTo(parent).setRange(0.00, 2.00).setPosition(10, 524).setValue(0.09).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; this.f_cv = cp5.addSlider("cohVal").plugTo(parent).plugTo(parent).setRange(0.00, 2.00).setPosition(10, 536).setValue(0.24).setDecimalPrecision(3).setSize(50, 10).setHandleSize(10).setColorForeground(color(255, 40)).setColorBackground(color(255, 40)) ; btypeA = cp5.addButton("Beh_A").plugTo(parent).setPosition(150, 10).setSize(100, 10); btypeA.setColorActive(color(0, 255, 0)); btypeA.setColorBackground(color(255, 0, 0)); btypeAA = cp5.addButton("Beh_AA").plugTo(parent).setPosition(255, 10).setSize(50, 10); btypeAA.setColorActive(color(0, 255, 0)); btypeAA.setColorBackground(color(255, 0, 0)); btypeAB = cp5.addButton("Beh_AB").plugTo(parent).setPosition(310, 10).setSize(50, 10); btypeAB.setColorActive(color(0, 255, 0)); btypeAB.setColorBackground(color(255, 0, 0)); btypeB = cp5.addButton("Beh_B").plugTo(parent).setPosition(150, 22).setSize(100, 10); btypeB.setColorActive(color(0, 255, 0)); btypeB.setColorBackground(color(255, 0, 0)); btypeC = cp5.addButton("Beh_C").plugTo(parent).setPosition(150, 34).setSize(100, 10); btypeC.setColorActive(color(0, 255, 0)); btypeC.setColorBackground(color(255, 0, 0)); btypeD = cp5.addButton("Beh_D").plugTo(parent).setPosition(150, 46).setSize(100, 10); btypeD.setColorActive(color(0, 255, 0)); btypeD.setColorBackground(color(255, 0, 0)); btypeE = cp5.addButton("Beh_E").plugTo(parent).setPosition(150, 58).setSize(100, 10); btypeE.setColorActive(color(0, 255, 0)); btypeE.setColorBackground(color(255, 0, 0)); } public void draw() { background(0); } public void createGui() { updateUI(); guiInit(); } public void updateUI() { if (cp5.isMouseOver()) { cam.setActive(false); } else { cam.setActive(true); } if (masterBehavior_A) { btypeA.setColorBackground(color(120, 255, 0)); } else { btypeA.setColorBackground(color(255, 0, 0)); } if (masterBehavior_B) { btypeB.setColorBackground(color(120, 255, 0)); } else { btypeB.setColorBackground(color(255, 0, 0)); } if (masterBehavior_C) { btypeC.setColorBackground(color(120, 255, 0)); } else { btypeC.setColorBackground(color(255, 0, 0)); } if (masterBehavior_D) { btypeD.setColorBackground(color(120, 255, 0)); } else { btypeD.setColorBackground(color(255, 0, 0)); } if (masterBehavior_E) { btypeE.setColorBackground(color(120, 255, 0)); } else { btypeE.setColorBackground(color(255, 0, 0)); } if (subBehavior_AA) { btypeAA.setColorBackground(color(120, 255, 0)); } else { btypeAA.setColorBackground(color(255, 0, 0)); } if (subBehavior_AB) { btypeAB.setColorBackground(color(120, 255, 0)); } else { btypeAB.setColorBackground(color(255, 0, 0)); } if (!masterBehavior_E) { this.f_sR.setVisible(false); this.f_av.setVisible(false); this.f_sv.setVisible(false); this.f_cv.setVisible(false); } else { this.f_sR.setVisible(true); this.f_av.setVisible(true); this.f_sv.setVisible(true); this.f_cv.setVisible(true); } if (toggleUI) { this.cbutt.setVisible(true); this.cbutt.setLabelVisible(true); this.cbut.setVisible(true); this.cbut.setLabelVisible(true); for (Slider s : sliderList) { s.setVisible(true); s.setLabelVisible(true); } } else { this.cbutt.setVisible(false); this.cbutt.setLabelVisible(false); this.cbut.setVisible(false); this.cbut.setLabelVisible(false); for (Slider s : sliderList) { s.setVisible(false); s.setLabelVisible(false); } } } void guiInit() { cp5.setAutoDraw(false); hint(DISABLE_DEPTH_TEST); cam.beginHUD(); cp5.draw(); cam.endHUD(); hint(ENABLE_DEPTH_TEST); } } Update
PATH
class Path { ArrayList<PVector> points; float radius = 20; boolean dim; Path() { this.points = new ArrayList<PVector>(); } void addPoint(float x, float y, float z) { PVector point = new PVector(x, y, z); this.points.add(point); } //------------------------------------------------------------------------------------- // Draw the path void display() { // Draw thick line for radius stroke(120,120,120,50); strokeWeight(radius*2); noFill(); beginShape(); for (PVector v : points) { vertex(v.x, v.y, v.z); } endShape(); // Draw thin line for center of path stroke(255); strokeWeight(1); noFill(); beginShape(); for (PVector v : points) { vertex(v.x, v.y, v.z); } endShape(); } } Update
TRACKER
import java.util.List; class Tracker { List<PVector> objectTrails; PVector speed, loc; PVector acc = new PVector(0, 0, 0); float maxforce = 0.01; float max = 4.0f; float vel = 1.0; float maxDist = 100; float r, amp; float wandertheta, wanderTVal, wanderD, wanderR, wanderT; float headWidth, strokeWidth, tranparency; boolean sepActive = false; boolean wonderTrigger = false; boolean instanceable; boolean dim; boolean randomize; int maxChildren = 0; int instanceTriggerCount; int seekerMT; int seekerChildMT; int minTrailPtCount = 0; int currentTrailSize = 0; String type, babyType; TColor colorA = TColor.newRGB(255.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f); TColor colorB = TColor.newRGB(120.0f, 0.0f, 0.0f); TColor colorB2 = TColor.newRGB(0.0f, 255.0f, 255.0f); TColor colorC = TColor.newRGB(187.0f / 255.0f, 216.0f / 255.0f, 40.0f / 255.0f); TColor colorD = TColor.newRGB(255.0f, 0.0f, 120.0f); TColor colorE = TColor.newRGB(200.0f / 60.0f, 160.0f / 100.0f, 80.0f / 30.0f); ColorGradient gradA = new ColorGradient(); ColorGradient gradB = new ColorGradient(); ColorGradient gradC = new ColorGradient(); ToneMap toneMapA, toneMapB, toneMapC; //-----------------Flocking Things----------------------------------------------------- String objectType; String behaviorType = "None"; PVector cummVec, alignVector, separateVector, cohesionVector; float maxSpeed, maxForce; float searchRad, av, sv, cv; List<PVector> otherPtsList; List<PVector> otherMoveValues; List<Float> allDist; List<Tracker> creeperCollection; ArrayList<PVector> creeperTrails; //------------------------------------------------------------------------------------- Tracker(PVector location, PVector Speed, boolean instance, String Type, String BabyType) { this.loc = location; this.objectTrails = new ArrayList<PVector>(); this.instanceTriggerCount = 0; this.instanceable = instance; this.type = Type; this.babyType = BabyType; this.speed = Speed; this.r = 12; this.gradA.addColorAt(0.0f, this.colorA); this.gradA.addColorAt(255.0f, this.colorC); this.toneMapA = new ToneMap(0.0f, 1.0f, this.gradA); this.gradB.addColorAt(0.0f, this.colorB); this.gradB.addColorAt(255.0f, this.colorB2); this.toneMapB = new ToneMap(0.0f, 1.0f, this.gradB); this.gradC.addColorAt(0.0f, this.colorD); this.gradC.addColorAt(255.0f, this.colorE); this.toneMapC = new ToneMap(0.0f, 1.0f, this.gradC); } //------------------------------------------------------------------------------------- //Run all of the other methods--------------------------------------------------------- //instanceable is whether or not current creeper is type parent or child, child cannot create instances //------------------------------------------------------------------------------------- void run() { if (enablePathTrack) { pathFollow(); } if (this.sepActive && this.instanceable && this.r != 0) { separate(); } if (masterBehavior_A || subBehavior_AA || subBehavior_AB) { if (enablePathTrack) { if (this.wonderTrigger) { wander(); } } else { wander(); } } if (masterBehavior_B) { this.wonderTrigger = true; this.randomize = true; wanderSolo(); } if (masterBehavior_C) { this.wonderTrigger = true; this.randomize = true; wanderSolo(); } if (masterBehavior_D) { this.wonderTrigger = true; this.randomize = true; wanderSolo(); } if (masterBehavior_E) { flock(); } if (simulate) { move(); } viz(); trail(); } //--------------------------------------------------------------------------------------- public void wanderSolo() { if (this.randomize) { this.wandertheta += random(-this.wanderT, this.wanderT); // Randomly change wander theta } else { this.wandertheta += this.wanderT; } PVector circleLoc = new PVector(this.speed.x, this.speed.y, this.speed.z); circleLoc.normalize(); // Normalize to get heading circleLoc.mult(this.wanderD); circleLoc.add(this.loc); PVector circleOffSet = new PVector(0, 0, 0); if (masterBehavior_B) { circleOffSet = new PVector(this.wanderR*cos(wandertheta), this.wanderR*sin(wandertheta), 0); } else if (masterBehavior_C) { circleOffSet = new PVector(this.wanderR*cos(wandertheta), this.wanderR*sin(wandertheta), random(this.wanderR*cos(wandertheta), this.wanderR*sin(wandertheta))); } else if (masterBehavior_D) { circleOffSet = new PVector(random(this.wanderR*cos(wandertheta), this.wanderR*sin(wandertheta)), random(this.wanderR*cos(wandertheta), this.wanderR*sin(wandertheta)), random(this.wanderR*cos(wandertheta), this.wanderR*sin(wandertheta))); } PVector target = circleLoc.add(circleOffSet); if (drawMovement) drawWanderStuff(this.loc, circleLoc, target, this.wanderR); // Render wandering circle, etc. PVector steer = target.sub(this.loc); steer.normalize(); steer.mult(1); this.acc.add(steer); } //------------------------------------------------------------------------------------- //Wandering Creeper---------------------------------------------------- //“Wandering is a type of random steering which has some long term order: the steering //direction on one frame is related to the steering direction on the next frame. This //produces more interesting motion than, for example, simply generating a random steering //direction each frame.” Reynolds //------------------------------------------------------------------------------------- void wander() { if (stepCount < this.wanderTVal) { if (this.type == "parent") { this.wandertheta = this.wanderT; } else if (this.type == "child") { if (this.babyType == "w_a") { this.wandertheta = this.wanderT; } else { this.wandertheta = -this.wanderT; } } } else if (stepCount >= this.wanderTVal && stepCount < this.wanderTVal*2) { if (this.type == "parent") { this.wandertheta = -this.wanderT; } else if (this.type == "child") { if (this.babyType == "w_a") { this.wandertheta = -this.wanderT; } else { this.wandertheta = this.wanderT; } } } else { stepCount = 0; } // Now we have to calculate the new location to steer towards on the wander circle PVector circleloc = this.speed.copy(); // Start with velocity circleloc.normalize(); // Normalize to get heading circleloc.mult(this.wanderD); // Multiply by distance circleloc.add(this.loc); // Make it relative to boid's location float h, headingXY, headingYZ, headingXZ; PVector circleOffSet; if (D2) { h = this.speed.heading(); circleOffSet = new PVector(this.wanderR*cos(this.wandertheta+h), this.wanderR*sin(this.wandertheta+h), 0); headingXZ = 0; headingYZ = 0; headingXY = 0; } else { headingXY = (float)Math.atan2(this.speed.y, this.speed.x); headingXZ = (float)Math.atan2(this.speed.z, this.speed.x); headingYZ = (float)Math.atan2(this.speed.y, this.speed.z); if (subBehavior_AA) { circleOffSet = new PVector(this.wanderR*cos(this.wandertheta+headingXY), this.wanderR*sin(this.wandertheta+headingXY), this.wanderR*cos(this.wandertheta+headingXZ)); } else if (subBehavior_AB) { circleOffSet = new PVector(this.wanderR*cos(this.wandertheta+headingXY), this.wanderR*sin(this.wandertheta+headingXY), (this.wanderR*cos(this.wandertheta+headingYZ) + this.wanderR*sin(this.wandertheta+headingXZ))/2); } else { circleOffSet = new PVector(this.wanderR*cos(this.wandertheta+headingXY), this.wanderR*sin(this.wandertheta+headingXY), random(this.wanderR*cos(this.wandertheta+(headingYZ + headingXZ)), this.wanderR*sin(this.wandertheta+(headingYZ + headingXZ)))); } } PVector target = PVector.add(circleloc, circleOffSet); seek(target); if (drawMovement) drawWanderStuff(this.loc, circleloc, target, this.wanderR); // Render wandering circle, etc. } //------------------------------------------------------------------------------------- //Draw the wandering creeper movements------------------------------------------------- //------------------------------------------------------------------------------------- // A method just to draw the circle associated with wandering void drawWanderStuff(PVector location, PVector circle, PVector target, float rad) { pushStyle(); stroke(255); noFill(); point(circle.x, circle.y, circle.z); popStyle(); pushStyle(); stroke(120); point(target.x, target.y, target.z); popStyle(); pushStyle(); stroke(160); strokeWeight(1); line(location.x, location.y, location.z, circle.x, circle.y, circle.z); line(circle.x, circle.y, circle.z, target.x, target.y, target.z); popStyle(); } //------------------------------------------------------------------------------------- //Setup for path following------------------------------------------------------------- //So lets check if we are inside the virtual path thickness, if we are and we can create //children then they would spawn here, depending on the max allowed etc. //------------------------------------------------------------------------------------- void pathFollow() { PVector predict = this.speed.copy(); predict.normalize(); predict.mult(this.amp); PVector nextPosPrev = PVector.add(loc, predict); PVector target = null; PVector normal = null; float worldRecord = 1000000; for (int z = 0; z < pathList.size(); z++) { for (int i = 0; i < pathList.get(z).points.size()-1; i++) { PVector a = pathList.get(z).points.get(i); PVector b = pathList.get(z).points.get(i+1); PVector normalPoint = getNormalPoint(nextPosPrev, a, b);//[offset-down] Finding the normals for each line segment if (D2) { if (normalPoint.x < min(a.x, b.x) || normalPoint.x > max(a.x, b.x)) { normalPoint = b.copy(); } } else { if ((normalPoint.x < min(a.x, b.x) || normalPoint.x > max(a.x, b.x)) || (normalPoint.y < min(a.y, b.y) || normalPoint.y > max(a.y, b.y)) || (normalPoint.z < min(a.z, b.z) || normalPoint.z > max(a.z, b.z))) { normalPoint = b.copy(); } } float distance = nextPosPrev.dist(normalPoint); if (distance < worldRecord) { worldRecord = distance; normal = normalPoint; PVector dir = PVector.sub(b, a); // Look at the direction of the line segment so we can seek a little bit ahead of the normal dir.normalize(); dir.mult(10); target = normalPoint.copy(); target.add(dir); } } } //remove if you want to just go to the line //maxDist = 10000000000000f; if (worldRecord < maxDist) { this.sepActive = true; this.wonderTrigger = true; if (worldRecord > tempPath.radius) { seek(target); } else { if (triggerSeekers && this.instanceable && this.instanceTriggerCount < this.maxChildren) { //check that we have not exceeded the amount of children we are allowed to create addNew = true; triggerLoc = nextPosPrev.copy(); childSpawners.add(new PVector(this.loc.x, this.loc.y, this.loc.z)); childSpawnType.add(this.instanceTriggerCount); triggerCount++; this.instanceTriggerCount ++; } else { addNew = false; } PVector zero = new PVector(0, 0, 0); zero.mult(3); acc.add(zero); } } else { this.wonderTrigger = false; } if (drawPathTargets) { // Draw predicted future location pushStyle(); stroke(255); strokeWeight(1); fill(0); popStyle(); if (D2) { ellipse(nextPosPrev.x, nextPosPrev.y, 4, 4); } else { pushStyle(); stroke(255, 255, 0); strokeWeight(10); point(nextPosPrev.x, nextPosPrev.y, nextPosPrev.z); popStyle(); pushStyle(); stroke(120); line(this.loc.x, this.loc.y, this.loc.z, nextPosPrev.x, nextPosPrev.y, nextPosPrev.z); popStyle(); } // Draw normal location pushStyle(); stroke(255); fill(0); if (D2) { ellipse(normal.x, normal.y, 4, 4); } else { pushStyle(); strokeWeight(4); point(normal.x, normal.y, normal.z); popStyle(); } popStyle(); pushStyle(); stroke(255); strokeWeight(2); // Draw actual target (red if steering towards it) line(nextPosPrev.x, nextPosPrev.y, nextPosPrev.z, normal.x, normal.y, normal.z); popStyle(); pushStyle(); if (worldRecord > tempPath.radius) fill(255, 0, 0); noStroke(); if (D2) { ellipse(target.x, target.y, 8, 8); } else { pushStyle(); stroke(255, 0, 0); strokeWeight(10); point(target.x, target.y, target.z); popStyle(); } popStyle(); } } //------------------------------------------------------------------------------------- //Gets the normal point of each path--------------------------------------------------- //Paths are comprised of multiple segments per path------------------------------------ PVector getNormalPoint(PVector p, PVector a, PVector b) { PVector ap = PVector.sub(p, a); PVector ab = PVector.sub(b, a); ab.normalize(); ab.mult(PVector.dot(ap, ab)); //Using the dot product for scalar projection PVector normalPoint = PVector.add(a, ab);// Finding the normal point along the line segment return normalPoint; } //------------------------------------------------------------------------------------- //Created the steering vector towards the target position------------------------------ //------------------------------------------------------------------------------------- void seek(PVector target) { PVector desired = PVector.sub(target, this.loc); desired.normalize(); desired.mult(this.max); PVector steer = desired.sub(this.speed); // Limit the magnitude of the steering force. steer.limit(this.maxforce); //acc.addSelf(steer); steer.mult(3); applyForce(steer); } //------------------------------------------------------------------------------------- //Apply Force to the acceleration------------------------------------------------------ //------------------------------------------------------------------------------------- void applyForce(PVector force) { acc.add(force); } //------------------------------------------------------------------------------------- //Move creeper to the next location---------------------------------------------------- //------------------------------------------------------------------------------------- void move() { if (!mathBehavior) { this.speed.add(this.acc); this.speed.limit(this.max); this.loc.add(this.speed); this.acc = new PVector(); } else { this.speed.add(this.acc); this.speed.normalize(); this.speed.mult(this.vel); this.speed.limit(this.max); this.loc.add(this.speed); this.acc = new PVector(); } } //------------------------------------------------------------------------------------- //Draw the heads and set values based on type------------------------------------------ //------------------------------------------------------------------------------------- void viz() { if (this.type == "parent" && headWidth != 0.0f) { stroke(191, 255, 0); strokeWeight(headWidth); point(this.loc.x, this.loc.y, this.loc.z); } else if (this.type == "child" && headWidth != 0.0f) { if (this.babyType == "w_a") { stroke(120, 75, 255); strokeWeight(headWidth/2); point(this.loc.x, this.loc.y, this.loc.z); } else { stroke(190, 255, 115); strokeWeight(headWidth/2); point(this.loc.x, this.loc.y, this.loc.z); } } } //------------------------------------------------------------------------------------- //Separation Method steers away from nearby dudes-------------------------------------- //------------------------------------------------------------------------------------- void separate () { float desiredseparation = this.r*2; PVector steer = new PVector(0, 0, 0); int count = 0; // check if we are too close for (int i = 0; i < agentList.size(); i++) { Tracker other = (Tracker) agentList.get(i); float d = loc.dist(other.loc); if ((d > 0) && (d < desiredseparation)) { PVector diff = PVector.sub(this.loc, other.loc); diff.normalize(); diff = PVector.mult(diff, (1.00f / d)); // Weight by distance steer.add(diff); count++; } } if (count > 0) { steer.mult(1.0/(float)count); } if (steer.mag() > 0) { //Steering = Desired - Velocity steer.normalize(); steer.mult(this.max); steer.sub(this.speed); steer.limit(this.maxforce); } steer.mult(3); applyForce(steer); } //------------------------------------------------------------------------------------- //Draw Tail and decay based on trail point amount-------------------------------------- //Trail is drawn from segment to segment and colored based on a tonemap---------------- //------------------------------------------------------------------------------------- void trail() { this.currentTrailSize++; if (this.currentTrailSize > this.minTrailPtCount) { this.objectTrails.add(new PVector(this.loc.x, this.loc.y, this.loc.z)); this.currentTrailSize = 0; } if (this.type == "parent") { //if the type is a parent then set the trail decay by removing backwards from the tail after a target is met if (this.objectTrails.size() > this.seekerMT) { this.objectTrails.remove(0); } } else if (this.type == "child") { //if the type is a child then set the trail decay by removing backwards from the tail after a target is met if (this.objectTrails.size() > this.seekerChildMT) { this.objectTrails.remove(0); } } if (this.objectTrails.size() > 0) { for (int j = 0; j < this.objectTrails.size(); j++) { if (j != 0) { PVector pos = objectTrails.get(j); PVector prevpos = objectTrails.get(j - 1); if (this.type == "parent") { int a = this.toneMapA.getARGBToneFor(j / (1.0f * this.objectTrails.size())); if (toggleColor) { stroke(a, map(j, 0, objectTrails.size(), 0, tranparency)); strokeWeight(map(j, 0, this.objectTrails.size(), 0.45, strokeWidth)); } else { stroke(255, 0, 0, map(j, 0, this.objectTrails.size(), 0, 200)); strokeWeight(map(j, 0, this.objectTrails.size(), 0.45, 1.5)); } } else if (this.babyType == "w_a") { int a = this.toneMapB.getARGBToneFor(j / (1.0f * this.objectTrails.size())); if (toggleColor) { stroke(a, map(j, 0, objectTrails.size(), 0, tranparency)); strokeWeight(map(j, 0, this.objectTrails.size(), 0.45, strokeWidth)); } else { stroke(0, 0, 255, map(j, 0, this.objectTrails.size(), 0, 200)); strokeWeight(map(j, 0, this.objectTrails.size(), 0.45, 1.0)); } } else { int a = this.toneMapC.getARGBToneFor(j / (1.0f * this.objectTrails.size())); if (toggleColor) { stroke(a, map(j, 0, objectTrails.size(), 0, tranparency)); strokeWeight(map(j, 0, this.objectTrails.size(), 0.45, strokeWidth)); } else { stroke(0, 255, 255, map(j, 0, this.objectTrails.size(), 0, 200)); strokeWeight(map(j, 0, this.objectTrails.size(), 0.45, 1.0)); } } line(pos.x, pos.y, pos.z, prevpos.x, prevpos.y, prevpos.z); } } } } void drawConnectivity(PVector conv) { pushStyle(); stroke(255, 255, 255, 150); strokeWeight(0.5); line(loc.x, loc.y, loc.z, conv.x, conv.y, conv.z); popStyle(); } void flock() { this.otherPtsList = new ArrayList<PVector>(); this.otherMoveValues = new ArrayList<PVector>(); this.allDist = new ArrayList<Float>(); Sphere bs = new Sphere(new Vec3D(this.loc.x, this.loc.y, this.loc.z), this.searchRad); occTreeList = octree.getPointsWithinSphere(bs); if (occTreeList!=null) { if (occTreeList.size()!=50402030) { for (int i = 0; i < occTreeList.size(); i++) { int index = vec3DList.indexOf((Vec3D)occTreeList.get(i)); if (drawConn) { Vec3D tconv = new Vec3D((Vec3D)occTreeList.get(i)); PVector conv = new PVector(tconv.x, tconv.y, tconv.z); drawConnectivity(conv); } Tracker other = (Tracker) creeperCollection.get(index); float distance = this.loc.dist(other.loc); if (distance != 0) { this.otherPtsList.add(other.loc); this.allDist.add(distance); if (index != -1) { this.otherMoveValues.add(other.speed); } } } } } if (this.otherPtsList.size() > 0) { this.cummVec = new PVector(); // ----------Align----------------- alignMethod(); if (this.alignVector.mag() > 0) { this.alignVector.normalize(); } this.alignVector.mult(this.av); // ----------Separate----------------- separateMethod(); if (this.separateVector.mag() > 0) { this.separateVector.normalize(); } this.separateVector.mult(this.sv); // ----------Cohesion----------------- cohesionMethod(); if (this.cohesionVector.mag() > 0) { this.cohesionVector.normalize(); } this.cohesionVector.mult(this.cv); // ----------------------------------- this.cummVec.add(this.alignVector); this.cummVec.add(this.separateVector); this.cummVec.add(this.cohesionVector); this.acc.add(this.cummVec); } } void separate(float searchRadius, float separateValue, List<Tracker> collection) { this.creeperCollection = collection; this.searchRad = searchRadius; this.sv = separateValue; this.otherPtsList = new ArrayList<PVector>(); this.otherMoveValues = new ArrayList<PVector>(); this.allDist = new ArrayList<Float>(); Sphere bs = new Sphere(new Vec3D(this.loc.x, this.loc.y, this.loc.z), this.searchRad); occTreeList = octree.getPointsWithinSphere(bs); if (occTreeList!=null) { if (occTreeList.size()!=50402030) { for (int i = 0; i < occTreeList.size(); i++) { int index = vec3DList.indexOf((Vec3D)occTreeList.get(i)); if (drawConn) { Vec3D tconv = new Vec3D((Vec3D)occTreeList.get(i)); PVector conv = new PVector(tconv.x, tconv.y, tconv.z); drawConnectivity(conv); } Tracker other = (Tracker) creeperCollection.get(index); float distance = this.loc.dist(other.loc); if (distance != 0) { this.otherPtsList.add(other.loc); this.allDist.add(distance); if (index != -1) { this.otherMoveValues.add(other.speed); } } } } } if (this.otherPtsList.size() > 0) { this.cummVec = new PVector(); // ----------Separate----------------- separateMethod(); if (this.separateVector.mag() > 0) { this.separateVector.normalize(); } this.separateVector.mult(this.sv); this.cummVec.add(this.separateVector); this.speed.add(this.cummVec); this.speed.normalize(); this.speed.mult(1.5f); } } void align(float searchRadius, float alignThreshold, List<Tracker> collection) { this.creeperCollection = collection; this.searchRad = searchRadius; this.av = alignThreshold; this.otherPtsList = new ArrayList<PVector>(); this.otherMoveValues = new ArrayList<PVector>(); this.allDist = new ArrayList<Float>(); Sphere bs = new Sphere(new Vec3D(this.loc.x, this.loc.y, this.loc.z), this.searchRad); occTreeList = octree.getPointsWithinSphere(bs); if (occTreeList!=null) { if (occTreeList.size()!=50402030) { for (int i = 0; i < occTreeList.size(); i++) { int index = vec3DList.indexOf((Vec3D)occTreeList.get(i)); if (drawConn) { Vec3D tconv = new Vec3D((Vec3D)occTreeList.get(i)); PVector conv = new PVector(tconv.x, tconv.y, tconv.z); drawConnectivity(conv); } Tracker other = (Tracker) creeperCollection.get(index); float distance = this.loc.dist(other.loc); if (distance != 0) { this.otherPtsList.add(other.loc); this.allDist.add(distance); if (index != -1) { this.otherMoveValues.add(other.speed); } } } } } if (this.otherPtsList.size() > 0) { this.cummVec = new PVector(); // ----------Align----------------- alignMethod(); if (this.alignVector.mag() > 0) { this.alignVector.normalize(); } this.alignVector.mult(this.av); // ----------------------------------- this.cummVec.add(this.alignVector); this.speed.add(this.cummVec); this.speed.normalize(); this.speed.mult(1.5f); } } void cohesion(float searchRadius, float cohesionValue, List<Tracker> collection) { this.creeperCollection = collection; this.searchRad = searchRadius; this.cv = cohesionValue; this.otherPtsList = new ArrayList<PVector>(); this.otherMoveValues = new ArrayList<PVector>(); this.allDist = new ArrayList<Float>(); Sphere bs = new Sphere(new Vec3D(this.loc.x, this.loc.y, this.loc.z), this.searchRad); occTreeList = octree.getPointsWithinSphere(bs); if (occTreeList!=null) { if (occTreeList.size()!=50402030) { for (int i = 0; i < occTreeList.size(); i++) { int index = vec3DList.indexOf((Vec3D)occTreeList.get(i)); if (drawConn) { Vec3D tconv = new Vec3D((Vec3D)occTreeList.get(i)); PVector conv = new PVector(tconv.x, tconv.y, tconv.z); drawConnectivity(conv); } Tracker other = (Tracker) creeperCollection.get(index); float distance = this.loc.dist(other.loc); if (distance != 0) { this.otherPtsList.add(other.loc); this.allDist.add(distance); if (index != -1) { this.otherMoveValues.add(other.speed); } } } } } if (this.otherPtsList.size() > 0) { this.cummVec = new PVector(); // ----------Cohesion----------------- cohesionMethod(); if (this.cohesionVector.mag() > 0) { this.cohesionVector.normalize(); } this.cohesionVector.mult(this.cv); // ----------------------------------- this.cummVec.add(this.cohesionVector); this.speed.add(this.cummVec); this.speed.normalize(); this.speed.mult(1.5f); } } void separateMethod() { this.separateVector = new PVector(); for (int i = 0; i < this.otherPtsList.size(); i++) { this.separateVector.add(PVector.mult(PVector.sub(this.loc, this.otherPtsList.get(i)), this.searchRad / this.allDist.get(i))); } } void alignMethod() { this.alignVector = new PVector(); for (int i = 0; i < this.otherPtsList.size(); i++) { this.alignVector.add(PVector.mult(this.otherMoveValues.get(i), this.searchRad / this.allDist.get(i))); } } void cohesionMethod() { this.cohesionVector = new PVector(); for (int i = 0; i < this.otherPtsList.size(); i++) { this.cohesionVector.add(this.otherPtsList.get(i)); } PVector scaleVec = PVector.mult(this.cohesionVector, (1.00f / this.otherPtsList.size())); float dist = this.loc.dist(scaleVec); this.cohesionVector = PVector.mult(PVector.sub(scaleVec, this.loc), this.searchRad / dist); } }
OCTREE
/** * Extends the default octree class in order to visualize currently * occupied cells in the tree. */ class VisibleOctree extends PointOctree { VisibleOctree(Vec3D o, float d) { super(o,d); } void draw() { drawNode(this); } void drawNode(PointOctree n) { if (n.getNumChildren() > 0) { noFill(); stroke(200, 20); pushMatrix(); translate(n.x, n.y, n.z); box(n.getNodeSize()); popMatrix(); PointOctree[] childNodes=n.getChildren(); for (int i = 0; i < 8; i++) { if(childNodes[i] != null) drawNode(childNodes[i]); } } } }
CONTROL
- s – pause/resume simulation
- w – new path
- q – draw path targets
- p – show/hide paths
- t – open/close trackBabies UI
- d – draw movement
- P – enable Path Tracking
- b – enable/disable spawning of children (will only spawn if inside the radius of path and spawning is enabled by this key)
- c – toggle color
- v – draw boundary
- o – show octree
- z – create octree
- 1 – draw flocking inter connectivity
- r – reset simulation
Recently in Portfolio
- Nike A.I.R Prototypes
- HE.6 2020 Prototype
- [A]nisochromatic Meshing
- PYTORCH-CLASSIFIER
- CULEBRA.NET
- Nike Zoom Superfly Elite
- Nike Footscape Flyknit DM
- Jordan Hyperdunk React
- KA-HELMET
- PARAPRAXIS
- [001.HRR] CONCEPT BIKE
- [C]ucarachas
- [S]eeker
- BENGBU CITY OPERA
- [O]h Baby
- [E]l Papa
- [S]hatter.Brain
- [S]tigmergy
- [F]orces
- CULEBRA.JAVA
- [C]ulebra.MultiBehaviors
- 2040:LUNAR.OUTPOST[a]
- [S]ticky Stuff
- [S]entinels
- [G]allopingTopiary
- [P]erlin
- [E]ternal Wanderers
- [W]heelie
- [M]esh Crawlers
- [E]l Nino
- [L]a Silla
- [3]D BabyMaking Trackstars
- [3]D Trackers
- [2]D BabyMaking Trackers
- [T]rackers
- CULEBRA GRASSHOPPER
- culebra.[M]eshCrawlers.3D
- culebra.[H]ybrid.3D
- culebra.[F]lorgy
- culebra.[F]ockers.3D
- culebra.[F]ockers.2D
- culebra.[N]oisey.3D
- culebra.[S]elfOrg
- [D]rippin
- [S]labacube
- culebra.[N]oisey.2D
- [C]reepyCrawlers
- [J]eepresesCreepers
- [C]reepers
- [T]2000
- RELUXOED
- [SRC] . Semi Rigid Car
- PUFFER PLEATNESS
- EMERGEN[CY]
- [L]iquified
- [S]uckedComp
- [X]plosion
- MR. EW
- [H]airGoo
- [B]alled
- [n]injaStars
- [b]loomer
- [t]rip city
- TAPE GUNNED
- [B]oom
- [M]iller Time
- [D]elamjam
- [B]rain Zapper
- [B]ig Bird
- IIIIIIII 00137
- [E]gg Tube Pavillion
- [A]llice’s Easter Tree
- [S]weet Honey
- [U]M.Urgent
- [t]oo.urgent
- [B]onnie..+..Clyde
- [B]io Mess
- [EL]Mojado.Virus
- [W]HAT the …!
- [H]ot Lava
- [P]leat Diddy
- [t]erminator easter egg
- Mr. BB
- [B]less You
- [J]acky Jack
- [F]antastic + Interactive
- [S]oo_Minimally_Pathed
- [P]uffer Fish.Fab
- [M]an Eater
- [F]ace Sukka
- [W]eave Machine
- Sportbike Racing
- Grappling
- Kart Racing
What a beautiful design! I want to know how you can make the track sure bright. I can use Rhino to make the lines. But how can I capture the drawing from Rhino? or you use rendering software to do that?
This video is using processing, I built the original library for java and used it in processing, later I built the .NET version that works with Grasshopper. You can download Culebra 2 and use that with Rhino & GH. I am actually updating it for Rhino 7 as well.