import org.jbox2d.util.nonconvex.*; import org.jbox2d.dynamics.contacts.*; //import org.jbox2d.testbed.*; import org.jbox2d.collision.*; import org.jbox2d.common.*; import org.jbox2d.dynamics.joints.*; import org.jbox2d.p5.*; import org.jbox2d.dynamics.*; boolean physics_mode; boolean rewind_mode; int rewind_frame; int rewind_speed = 1; int noiseIndex = 0; Form cube; float fuzzrad = 3; PFont the_font; ArrayList frames; PImage current_frame; Physics physics; void draw() { background(40); fill(255); /* textFont(the_font); text("Project Decomposition", 20, 20); noFill(); */ stroke(255); if (!physics_mode && !rewind_mode) { cube.turn(noise(float(noiseIndex+3000)/100)/50,noise(float(noiseIndex+40)/100)/200,noise(float(noiseIndex)/300)/200); cube.render(); noiseIndex += 3; } if (rewind_mode) { PImage display_frame = (PImage) frames.get(rewind_frame); image(display_frame,0,0); rewind_frame -= rewind_speed; if (rewind_frame <= 0) { rewind_mode = false; frames = new ArrayList(); } } } void setup() { physics_mode = false; rewind_mode = false; rewind_frame = 0; frameRate(33); smooth(); strokeWeight(2); strokeCap(ROUND); size(400,400); current_frame = get(); frames = new ArrayList(); InitScene(); cube = new Form(8, width/8, width/2, height/2); cube.setPoint(0, -1, -1, -1); cube.setPoint(1, -1, -1, 1); cube.setPoint(2, -1, 1, -1); cube.setPoint(3, -1, 1, 1); cube.setPoint(4, 1, -1, -1); cube.setPoint(5, 1, -1, 1); cube.setPoint(6, 1, 1, -1); cube.setPoint(7, 1, 1, 1); boolean coin = (random(0,1) > 0.5); for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { int xres = i ^ j; if ((xres == 1) || (xres == 2) || (xres == 4)) { cube.connect(i,j); } } } the_font = loadFont("Petra-12.vlw"); } void InitScene() { // Set up the engine with the sketch's dimensions physics = new Physics(this, width, height); physics.setCustomRenderingMethod(this, "myCustomRenderer"); physics.setRestitution(0.8); physics.setFriction(0.35); physics.setDensity(1.0); } void myCustomRenderer(World world) { if (!physics_mode) { return; } fill(255); // iterate through the bodies Body body; int body_count = 0; for (body = world.getBodyList(); body != null; body = body.getNext()) { body_count++; // iterate through the shapes of the body org.jbox2d.collision.Shape shape; for (shape = body.getShapeList(); shape != null; shape = shape.getNext()) { // find out the shape type ShapeType st = shape.getType(); if (st == ShapeType.POLYGON_SHAPE) { if (body.getMass() == 0) { continue; } // polygon? let's iterate through its vertices while using begin/endShape() PolygonShape poly = (PolygonShape) shape; int count = poly.getVertexCount(); Vec2[] verts = poly.getVertices(); for(int i = 0; i < count; i++) { Vec2 vert_a = physics.worldToScreen(body.getWorldPoint(verts[i])); Vec2 vert_b = physics.worldToScreen(body.getWorldPoint(verts[(i+1)%count])); line(vert_a.x,vert_a.y,vert_b.x,vert_b.y); } Vec2 firstVert = physics.worldToScreen(body.getWorldPoint(verts[0])); } else if (st == ShapeType.CIRCLE_SHAPE) { // circle? let's find its center and radius and draw an ellipse CircleShape circle = (CircleShape) shape; Vec2 pos = physics.worldToScreen(body.getWorldPoint(circle.getLocalPosition())); float radius = physics.worldToScreen(circle.getRadius()); ellipseMode(CENTER); ellipse(pos.x, pos.y, radius*2, radius*2); // we'll add one more line to see how it rotates line(pos.x, pos.y, pos.x + radius*cos(-body.getAngle()), pos.y + radius*sin(-body.getAngle())); } } } current_frame = get(); frames.add(current_frame); } void mousePressed() { if (!physics_mode) { physics_mode = true; println("----"); Form dissolved = cube.dissolve(); ArrayList cycles = dissolved.cycles(); for (int i = cycles.size()-1; i >= 0; i--) { ArrayList cycle = (ArrayList) cycles.get(i); float[] interleaved = new float[2*cycle.size()-2]; for (int j = 0; j < cycle.size()-1; j++) { int x = (Integer) cycle.get(j); PVector the_point = dissolved.getPoint(x); interleaved[j*2] = the_point.x; interleaved[(j*2)+1] = the_point.y; } println(); Body new_body = physics.createPolygon(interleaved); new_body.setAngularVelocity(random(PI,-PI)/float(20)); new_body.setLinearVelocity(new Vec2( random(-2,2), random(-5,10))); } } } void mouseReleased() { if (frames.size() >= 1) { physics_mode = false; for (Body body = physics.getWorld().getBodyList(); body != null; body = body.getNext()) { if( body.getMass() > 0) { physics.removeBody(body); } } rewind_mode = true; rewind_speed = (int) random(1,4); rewind_frame = frames.size()-1; PImage display_frame = (PImage) frames.get(rewind_frame); image(display_frame,0,0); } }