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
- [K]ernels

- Nike A.I.R Prototypes

- [A]nisochromatic Meshing

- Nike After Dark Tour

- PARAPRAXIS

- [001.HRR] CONCEPT BIKE

- 2040:LUNAR.OUTPOST[a]

- HE.6 2020 Prototype

- CULEBRA.NET

- PYTORCH-CLASSIFIER

- Nike Zoom Superfly Elite

- BENGBU CITY OPERA

- Nike Footscape Flyknit DM

- Jordan Hyperdunk React

- KA-HELMET

- [C]ucarachas

- [S]eeker

- [O]h Baby

- [E]l Papa

- [S]hatter.Brain

- [S]tigmergy

- [F]orces

- CULEBRA.JAVA

- [C]ulebra.MultiBehaviors

- [S]ticky Stuff

- [S]entinels

- [G]allopingTopiary

- RELUXOED

- [SRC] . Semi Rigid Car

- [P]erlin

- [E]ternal Wanderers

- [W]heelie

- [S]labacube

- [M]esh Crawlers

- [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

- [E]l Nino

- culebra.[S]elfOrg

- [D]rippin

- culebra.[N]oisey.2D

- [C]reepyCrawlers

- [J]eepresesCreepers

- [T]2000

- 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

- [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

- [F]antastic + Interactive

- [S]oo_Minimally_Pathed

- [P]uffer Fish.Fab

- [M]an Eater

- [AHH] Alien House Hunters

- [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.