How allow collision with a Distance joint in box2d

edited April 2017 in Library Questions

I have a series of particles attached by a Distance Joint (using Processing with box2d). The particles have to be a certain size. I want to throw bricks at the chain of particles and for the bricks to bounce off. At the moment the bricks bounce off the particles but not the joint. How can I make them do so. My MCVE:

import shiffman.box2d.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.contacts.*;
import org.jbox2d.particle.ParticleGroupDef;
import org.jbox2d.particle.ParticleSystem;
import org.jbox2d.particle.ParticleType;
import org.jbox2d.particle.ParticleDef;

import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
// A reference to our box2d world
Box2DProcessing box2d;
ParticleSystem particleSystem;
ParticleDef pd=new ParticleDef();
Bridge bridge;
int PARTICLES = 10; // the amount of particles in your bridge
 ParticleDef pdef=new ParticleDef();
// A list for all of our rectangles
ArrayList<Box> boxes;


void setup() {

  size(1040,1060);
  smooth();

  // Initialize box2d physics and create the world
  box2d = new Box2DProcessing(this);
  box2d.createWorld();
  // Make the bridge total length,number of points,x start position
  bridge = new Bridge(width,PARTICLES,200);
  // Create ArrayLists  
  boxes = new ArrayList<Box>();


}
void draw() {
   background(255);

  // We must always step through time!
  box2d.step();

  // When the mouse is clicked, add a new Box object
  if (mousePressed) {
    Box p = new Box(mouseX,mouseY);
    boxes.add(p);
  }



  // Display all the boxes
  for (Box b: boxes) {
    b.display();
  }

  // Boxes that leave the screen, we delete them (note they have to be deleted from both the box2d world and our list
  for (int i = boxes.size()-1; i >= 0; i--) {
    Box b = boxes.get(i);
    if (b.done()) {
      boxes.remove(i);
    }
  }

 bridge.display();

 fill(0);
       float move_1=300;
    for (int i=0; i<10; i++){
            bridge.particles.get(i).body.setTransform(box2d.coordPixelsToWorld(move_1+10,i*20+70), 0);
    }

}

// A rectangular box
class Box  {

  // We need to keep track of a Body and a width and height
  Body body;
  float w;
  float h;

  // Constructor
  Box(float x, float y) {
    w = random(4,16);
    h = random(4,16);
    // Add the box to the box2d world
    makeBody(new Vec2(x,y),w,h);
  }

  // This function removes the particle from the box2d world
  void killBody() {
    box2d.destroyBody(body);
  }

  // Is the particle ready for deletion?
  boolean done() {
    // Let's find the screen position of the particle
    Vec2 pos = box2d.getBodyPixelCoord(body);
    // Is it off the bottom of the screen?
    if (pos.y > height+w*h) {
      killBody();
      return true;
    }
    return false;
  }

  // Drawing the box
  void display() {
    // We look at each body and get its screen position
    Vec2 pos = box2d.getBodyPixelCoord(body);
    // Get its angle of rotation
    float a = body.getAngle();

    rectMode(CENTER);
    pushMatrix();
    translate(pos.x,pos.y);
    rotate(-a);
    fill(175);
    stroke(0);
    rect(0,0,w,h);
    popMatrix();
  }

  // This function adds the rectangle to the box2d world
  void makeBody(Vec2 center, float w_, float h_) {

    // Define a polygon (this is what we use for a rectangle)
    PolygonShape sd = new PolygonShape();
    float box2dW = box2d.scalarPixelsToWorld(w_/2);
    float box2dH = box2d.scalarPixelsToWorld(h_/2);
    sd.setAsBox(box2dW, box2dH);

    // Define a fixture
    FixtureDef fd = new FixtureDef();
    fd.shape = sd;
    // Parameters that affect physics
    fd.density = 1;
    fd.friction = 300;
    fd.restitution = 0.0;

    // Define the body and make it from the shape
    BodyDef bd = new BodyDef();
    bd.type = BodyType.DYNAMIC;
    bd.position.set(box2d.coordPixelsToWorld(center));

    body = box2d.createBody(bd);
    body.createFixture(fd);
    // Give it some initial random velocity
   body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5)));

  }

}


// Series of Particles connected with distance joints

class Bridge {

  // Bridge properties
  float totalLength;  // How long
  int numPoints;      // How many points in a line
  int NewCurvepoints; // How many points in a curve for the top of the stomach
  // Our chain is a list of particles
  ArrayList<Particle> particles;

  // Chain constructor
  Bridge(float l, int n,int start) {

    totalLength = l;
    numPoints = n;
    NewCurvepoints=n;
    particles = new ArrayList();
    float len = totalLength / numPoints;

    // Add particles to the chain    
    for(int i=0; i < PARTICLES; i++) {
      // Make a new particle
      Particle p = null;     
      //x,y,radius,fixed
            p = new Particle(start,i*len,7,3);

      particles.add(p);
      if (i > 0) {
         DistanceJointDef djd = new DistanceJointDef();
         Particle previous = particles.get(i-1);
         djd.bodyA = previous.body;
         djd.bodyB = p.body;
         djd.length = box2d.scalarPixelsToWorld(len/40);
         line(djd.bodyA.getPosition().x,djd.bodyA.getPosition().y,djd.bodyB.getPosition().x,djd.bodyB.getPosition().y);
         djd.frequencyHz = 0;
         djd.dampingRatio = 0;
         DistanceJoint dj = (DistanceJoint) box2d.world.createJoint(djd);
      }
    }

     }

 // // Draw the bridge
  void display() { for(int i=0; i < particles.size()-1; i++) {
    Vec2 pos1 = box2d.getBodyPixelCoord(particles.get(i).body);
    Vec2 pos2 = box2d.getBodyPixelCoord(particles.get(i+1).body);
    stroke(0);
    strokeWeight(2);
    line(pos1.x,pos1.y,pos2.x,pos2.y);
  }
    for (Particle p: particles) {
      p.display();
    }
  }

}

class Particle {

  // We need to keep track of a Body and a radius
  Body body;
  float r;

  color col;

  Particle(float x, float y, float r_, int fixed) {
    r = r_;    
    // Define a body
    BodyDef bd = new BodyDef();
    bd.fixedRotation=true;
    if (fixed==1) bd.type = BodyType.STATIC;
    else if (fixed==2) bd.type = BodyType.KINEMATIC;
    else if (fixed==3) bd.type = BodyType.DYNAMIC;

    // Set its position
    bd.position = box2d.coordPixelsToWorld(x,y);
    body = box2d.world.createBody(bd);

    // Make the body's shape a circle
    CircleShape cs = new CircleShape();
    cs.m_radius = box2d.scalarPixelsToWorld(r);

    FixtureDef fd = new FixtureDef();
    fd.shape = cs;
    // Parameters that affect physics
    fd.density = 0;
    fd.friction = 0;
    fd.restitution = -90;
    body.createFixture(fd);
    col = color(175);
    //determine how it moves
  }


  // 
  void display() {
    // We look at each body and get its screen position
    Vec2 pos = box2d.getBodyPixelCoord(body);
    // Get its angle of rotation
    float a = body.getAngle();
    pushMatrix();
    translate(pos.x,pos.y);
    rotate(a);
    fill(col);
    stroke(0);
    strokeWeight(1);
    ellipse(0,0,r*2,r*2);
    // Let's add a line so we can see the rotation
    line(0,0,r,0);
    popMatrix();
  }


}
Tagged:
Sign In or Register to comment.