Hey!
Thanks for the reply, it always amazes me how you have the time to take a personal interest in people using your libraries, having seen you at semi-permanent in Auckland and trying to imagine your insane work load!
Thanks for the code, I will have a look at it. In the meantime I got around the problem by using a live-update that replaces all the forces on each update. I know this is probably painful to look at in terms of efficiency but it works for now, the main issue I was having is trying to modify effectively a mouseAttractor (from your example) as
physics.behavior.get(behavior id that matches the particle I want to select).setStrength(0.9f);
Heres the code I had working, at this point it sets all behaviors to the same thing:
- import toxi.geom.*;
- import toxi.physics.*;
- import toxi.physics.behaviors.*;
- import processing.opengl.*;
- import java.util.*;
- VerletPhysics physics;
- GravityBehavior gravForce;
- AttractionBehavior attForce;
- AttractionBehavior repForce;
- boolean boolGravity = true;
- boolean boolAttForce = true;
- boolean boolRepForce = true;
- float i = 0;
- int particleSelect=0;
- boolean stopMake = false;
- void setup(){
- size(900,600,OPENGL);
- sphereDetail(1);
-
- physics = new VerletPhysics();
- physics.setDrag(0.05f);
- physics.setWorldBounds(new AABB(200));
- setForce();
- }
- void draw(){
- background(100);
-
- lights();
- camera();
- action();
- }
- void camera(){
- float cameraY = height;
- float fov = 1;
- float cameraZ = cameraY / tan(fov / 2.0);
- float aspect = float(width)/float(height);
- perspective(fov, aspect, cameraZ/10.0, cameraZ*10.0);
- translate(width/2, height/2, 0);
- rotateX(PI/3 + mouseY/float(height) * 2 * PI);
- rotateY(PI/3 + mouseX/float(height) * 2 * PI);
- }
- void action(){
- makeParticles();
- drawParticles();
- setForce();
- physics.update();
- }
- void makeParticles(){
- if(physics.particles.size() < 10 && stopMake == false){
- VerletParticle p = new VerletParticle(random(-100,100),random(-100,100),random(-100,100),1);
- physics.addParticle(p);
- particleSelect=physics.particles.size()-1;
- }else{stopMake = true;}
- }
- void drawParticles(){
- for (VerletParticle p: physics.particles)
- {
- pushMatrix();
- translate(p.x,p.y,p.z);
- noFill();
- if(physics.particles.indexOf(p) == particleSelect ){
- fill(255,0,0);
- sphere(20);
- }
-
- int indexVar = physics.particles.indexOf(p);
- sphere(5);
- popMatrix();
- stroke(physics.particles.indexOf(p)*2,255,255-physics.particles.indexOf(p)*2);
- }
- }
- void setForce() {
- physics.behaviors.clear();
-
- i = i + 0.005;
- println(sin(i));
-
- attForce = new AttractionBehavior(new Vec3D(),100000,0.1,0.01f);
- physics.addBehavior(attForce);
- repForce = new AttractionBehavior(new Vec3D(),(sin(i)+1)*100,-2,0.01f);
- physics.addBehavior(repForce);
-
- for (VerletParticle p : physics.particles)
- {
- //physics.addBehavior(new AttractionBehavior(p,100000,0.1,0.001f));
- //physics.addBehavior(new AttractionBehavior(p,(sin(i)+1.5)*100,-2,0.001f));
- }
- }
- void mousePressed()
- {
- if (mouseButton == LEFT)
- {
- for(int j = 0; j < 10; j++){
- VerletParticle p = new VerletParticle(random(-100,100),random(-100,100),random(-100,100),1);
- physics.addParticle(p);
- particleSelect = physics.particles.size()-1;
- }
- }
- if (mouseButton == RIGHT)
- {
- if (physics.particles.size() > 0){
- physics.removeParticle(physics.particles.get(particleSelect));
- particleSelect = particleSelect - 1;
- }
- }
- }
And heres what had me confused..
- import toxi.geom.*;
- import toxi.physics.*;
- import toxi.physics.behaviors.*;
- import processing.opengl.*;
- import java.util.*;
- VerletPhysics physics;
- GravityBehavior gravForce;
- AttractionBehavior attForce;
- AttractionBehavior repForce;
- void setup() {
- size(1200,800,OPENGL);
- smooth();
-
- physics = new VerletPhysics();
- physics.setDrag(0.05f);
- gravForce = new GravityBehavior(new Vec3D(0,0.01,0));
- physics.addBehavior(gravForce);
- attForce = new AttractionBehavior(new Vec3D(),100000,1,0.01f);
- physics.addBehavior(attForce);
- repForce = new AttractionBehavior(new Vec3D(),500,-2,0.01f);
- physics.addBehavior(repForce);
- }
- int particleSelect = 0;
- void draw() {
- background(100);
- lights();
- stroke(255);
- camera();
-
- if(physics.particles.size() < 100){
- VerletParticle p = new VerletParticle(random(-100,100),random(-100,100),random(-100,100),random(0.1,10));
- physics.addParticle(p);
- }
-
-
- for (VerletParticle p: physics.particles)
- {
- pushMatrix();
- translate(p.x,p.y,p.z);
- fill(255);
- int indexVar = physics.particles.indexOf(p);
- box(10);
- popMatrix();
-
- stroke(255);
- point(p.x,p.y,p.z);
- }
-
- physics.update();
- }
- void camera(){
- float cameraY = height;
- float fov = 1;
- float cameraZ = cameraY / tan(fov / 2.0);
- float aspect = float(width)/float(height);
- perspective(fov, aspect, cameraZ/10.0, cameraZ*10.0);
- translate(width/2, height/2, 0);
- rotateX(PI/3 + mouseY/float(height) * 2 * PI);
- rotateY(PI/3 + mouseX/float(height) * 2 * PI);
- }
- void mousePressed()
- {
- if (mouseButton == LEFT)
- {
-
- for (int i = 0; i < physics.behaviors.size(); i++)
- //for (ParticleBehavior b : physics.behaviors) //throws a ConcurrentModificationException
- {
- physics.behaviors.remove(physics.behaviors.get(i));
- println(physics.behaviors.size());
- print(i + ",");
- }
-
- //physics.behaviors.clear();
-
- println(physics.behaviors);
- println(physics.behaviors.size());
- }
- if (mouseButton == RIGHT)
- {
- attForce = new AttractionBehavior(new Vec3D(),100000,random(0,1),0.01f);
- physics.addBehavior(attForce);
- repForce = new AttractionBehavior(new Vec3D(),500,-random(1,-2),0.01f);
- physics.addBehavior(repForce);
- for (VerletParticle p : physics.particles)
- {
- physics.addBehavior(new AttractionBehavior(p,10000,0.1,0.01));
- physics.addBehavior(new AttractionBehavior(p,100,-1,0.01));
- }
- }
- }
Apart from the concurrent modification exception, this program only seems to delete half the particle behaviours at a time even though the loop is going from 0 to particle.behaviors.size() since for (ParticleBehavior b : physics.behaviors) throws a ConcurrentModificationException. Again it's probably very obvious but I went through the docs several times and got confused.
Effectively what I want to do is select a subset of particles (say in a string) and affect their behaviours separately from everything else, so then I can call a function called say setRepDist(particle indexes, repulsion distance); where particle indexes are an arraylist (or nested array) containing the integers I can use to do something like
- //This gets called every time I want to change the radius
- void setForce(ArrayList particleIndexList,ArrayList radiusIndexList,float strength){
- physics.behaviors.clear(); //because a remove(index) loop and setRadius didn't seem to work
- //reinstate global behaviors etc
- <behaviors go here>;
- //adjust radius (in this case)
- for (int i = 0; i < particleIndexList.size(); i++){
- int j = particleIndexList.get(i);
- float radius = radiusIndexList.get(i);
- physics.addBehavior(new AttractionBehavior(physics.particles.get(j),radius,strength));
- }
- }
Whereas what I was trying to do before I got confused by the divide behaviours by two example above (and related problems including various concurrent modification exceptions) was more like
- //behaviorList is a nested list of behaviors that I get by adding every particle/behavior to a list with related indexes eg.
- //for(int foobar = 0; foobar < particleAddLimit; foobar++){
- //physics.addParticle();
- //particleList.add(foobar, physics.particles.size()-1);
- //physics.addBehavior();
- //behaviorList.add(foobar, physics.behaviors.size()-1);
- //}
- // then add these two lists to a superList so I can retrieve them
- void setRadius(behaviorList, newRadius){
- for(int i = 0; i < behaviorList.size;i++){
- physics.behaviors.get(behaviorList.get(i)).setRadius(newRadius);
- }
- }
- //but like I said, I couldn't get this method to work even after fixing the problems like behaviorList.get(i) is not an int etc.
I know this probably seems like a mental way to get around the problem but I'm just starting out and anything that works is a plus, if you or anyone could explain the /right/ way to do what I'm trying to do I'll be happier than a pig in mud,
Thanks heaps!