import processing.opengl.*; static final float max_width = 800; static final float max_height = 600; static final int max_dimension = 3; //the dimension static final int max_swarms = 40; static final int max_resource_emitters = 10; static final int max_particles_per_swarm = 10; static final float min_x = 0; static final float max_x = max_width; static final float min_y = 0; static final float max_y = max_height; static final float min_z = -500; static final float max_z = 100; static final float max_particle_velocity_magnitude = 300; static final float resource_mouse_pressed_rate = 30; static final float resource_spawn_prob = 250; static final float max_resource_spawn_value = 10; static final float max_resource_growth_rate = 5; static final float max_resource_value = 300; static final int MODE_MODIFY_INERTIA_FACTOR = 0; static final int MODE_MODIFY_SELFISH_FACTOR = 1; static final int MODE_MODIFY_SOCIAL_FACTOR = 2; static final int MODE_MODIFY_DEFIANCE_FACTOR = 3; static final int MODE_MODIFY_RANDOM_SEARCH_RADIUS = 4; ResourceField rf; Vector swarms; int mode; float mouse_last_pressed_millis; float x_rot_light = 0; void setup() { //model = new OBJModel(this); //model.load("swarm.obj"); // swarm.obj in data folder size((int)max_width,(int)max_height,P3D); sphereDetail(10); //smooth(); frameRate(30); rf = new ResourceField(max_dimension); rf.setBounds(min_x, max_x, 0); rf.setBounds(min_y, max_y, 1); rf.setBounds(min_z, max_z, 2); //for (int i = 0; i < max_dimension; i++) //{ // rf.setBounds(lower_bound, upper_bound, i); //} swarms = new Vector(); //int ms = (int)random(max_swarms - 1) + 1; //for (int i = 0; i < ms; i++) //{ addSwarm(random(width), random(height), (int)random(max_particles_per_swarm-1) + 1); //} } public void addSwarm(float x, float y, int num_particles) { GnatSwarm s; Gnat p; color h; float in_f, so_f, se_f, d_f; s = new GnatSwarm(rf); h = color(random(255), random(255), random(255)); in_f = random(1,1.2); so_f = random(1, 3); se_f = random(.4, .6); d_f = .2; for(int j = 0; j < num_particles; j++) { p = new Gnat(max_dimension); p.setUseTime(true); p.setHasMaxVelocityMagnitude(true); p.setMaxVelocityMagnitude(random(max_particle_velocity_magnitude)); p.setDefianceFactor(d_f); p.setRandomSearchRadius(20); p.setInertiaFactor(in_f); p.setSelfishFactor(se_f); p.setSocialFactor(so_f); p.setConsumptionRate(2); p.setMetabolicRate(.1); p.setNutrition(random(15)); p.setReproductionRate(random(5,20)); p.setFillColor( color(red(h), green(h), blue(h), random(255))); s.addParticle(p); p.setPosition(rf.getRandomPosition()); } swarms.add(s); } public void draw() { if ((int)random(resource_spawn_prob) == 0) { addResourceEmitter(random(max_x - min_x) + min_x, random(max_y - min_y) + min_y, 0, random(max_resource_spawn_value), random(max_resource_growth_rate), random(max_resource_value)); } rf.update(); Swarm s; for (int i = 0; i < swarms.size(); i++) { s = (Swarm) swarms.get(i); s.update(); if (s.getParticleCount() == 0) { swarms.remove(i); i--; } } background(0,0,0,1); //ambientLight(102, 102, 102); //lightSpecular(0, 0, 0); x_rot_light = (x_rot_light + 1) % 360; directionalLight(255, 255, 255, cos(radians(x_rot_light)), 0, -1); //directionalLight(230, 230, 230, 0, 0, -1); //specular(0, 0, 0); shininess(.4); noStroke(); pushMatrix(); rf.display(); for (int i = 0; i < swarms.size(); i++) { s = (Swarm) swarms.get(i); s.display(); } popMatrix(); } void mousePressed() { mouse_last_pressed_millis = millis(); } void mouseReleased() { float time_elapsed = (millis() - mouse_last_pressed_millis)/1000; if (mouseButton == RIGHT || (keyPressed == true && keyCode == CONTROL)) { if (swarms.size() < max_swarms) { addSwarm(mouseX, mouseY, 5); } } else { float ev = resource_mouse_pressed_rate * time_elapsed + 20; if (ev > max_resource_value) { ev = max_resource_value; } addResourceEmitter((float)mouseX, (float)mouseY, (float)0, ev, random(max_resource_growth_rate), random(max_resource_value)); } } void keyPressed() { char k = key; int c_k = keyCode; switch(k) { case '1': mode = MODE_MODIFY_SELFISH_FACTOR; break; case '2': mode = MODE_MODIFY_SOCIAL_FACTOR; break; case '3': mode = MODE_MODIFY_DEFIANCE_FACTOR; break; case '4': mode = MODE_MODIFY_INERTIA_FACTOR; break; case '5': mode = MODE_MODIFY_RANDOM_SEARCH_RADIUS; break; } Swarm s; Gnat p; for (int i = 0; i < swarms.size(); i++) { s = (Swarm) swarms.get(i); for(int j = 0; j < s.particles.size(); j++) { p = (Gnat)s.particles.get(j); switch(mode) { case MODE_MODIFY_SELFISH_FACTOR: if (keyCode == UP) { p.setSelfishFactor(p.getSelfishFactor() + .1); } else if (keyCode == DOWN) { p.setSelfishFactor(p.getSelfishFactor() - .1); } break; case MODE_MODIFY_SOCIAL_FACTOR: if (keyCode == UP) { p.setSocialFactor(p.getSocialFactor() + .1); } else if (keyCode == DOWN) { p.setSocialFactor(p.getSocialFactor() - .1); } break; case MODE_MODIFY_DEFIANCE_FACTOR: if (keyCode == UP) { p.setDefianceFactor(p.getDefianceFactor() + .1); } else if (keyCode == DOWN) { p.setDefianceFactor(p.getDefianceFactor() - .1); } break; case MODE_MODIFY_INERTIA_FACTOR: if (keyCode == UP) { p.setInertiaFactor(p.getInertiaFactor() + .1); } else if (keyCode == DOWN) { p.setInertiaFactor(p.getInertiaFactor() - .1); } break; case MODE_MODIFY_RANDOM_SEARCH_RADIUS: if (keyCode == UP) { p.setRandomSearchRadius(p.getRandomSearchRadius() + 50); } else if (keyCode == DOWN) { p.setRandomSearchRadius(p.getRandomSearchRadius() - 50); } break; } } } } void addResourceEmitter(float x, float y, float z, float resource_amount, float resource_growth_rate, float max_resource_value) { if (rf.getEmitterCount() > max_resource_emitters) { return; } if (max_resource_value < resource_amount) { max_resource_value = resource_amount; } Tuple t = new Tuple(max_dimension); for(int i = 0; i < max_dimension && i < 3; i++) { if (i == 0) { t.setValue(x, 0); } else if (i == 1) { t.setValue(y, 1); } else { t.setValue(z, i); } } rf.addEmitter(new ResourceEmitter(t, "food", resource_amount, resource_growth_rate, max_resource_value)); }