Beispiel #1
0
  @Override
  public void start() {
    super.start();

    environment =
        new Continuous2D(1.0, config.getEnvironmentWidth(), config.getEnvironmentHeight());
    drawProxy = new DrawProxy(environment.getWidth(), environment.getHeight());
    environment.setObjectLocation(drawProxy, new Double2D());

    physicsWorld = new World(new Vec2());
    placementArea =
        new PlacementArea((float) environment.getWidth(), (float) environment.getHeight());
    placementArea.setSeed(config.getSimulationSeed());
    schedule.reset();
    System.gc();

    physicsWorld.setContactListener(contactListener);

    // Create ALL the objects
    createWalls();
    createTargetArea();
    robotFactory.placeInstances(
        placementArea.new ForType<>(), physicsWorld, config.getTargetAreaPlacement());
    config.getResourceFactory().placeInstances(placementArea.new ForType<>(), physicsWorld);

    // Now actually add the objects that have been placed to the world and schedule
    for (PhysicalObject object : placementArea.getPlacedObjects()) {
      drawProxy.registerDrawable(object.getPortrayal());
      schedule.scheduleRepeating(object);
    }

    schedule.scheduleRepeating(
        simState -> physicsWorld.step(TIME_STEP, VELOCITY_ITERATIONS, POSITION_ITERATIONS));
  }
Beispiel #2
0
  /**
   * Creates a fixture and attach it to this body. Use this function if you need to set some fixture
   * parameters, like friction. Otherwise you can create the fixture directly from a shape. If the
   * density is non-zero, this function automatically updates the mass of the body. Contacts are not
   * created until the next time step.
   *
   * @param def the fixture definition.
   * @warning This function is locked during callbacks.
   */
  public final Fixture createFixture(FixtureDef def) {
    assert (m_world.isLocked() == false);

    if (m_world.isLocked() == true) {
      return null;
    }

    // djm TODO from pool?
    Fixture fixture = new Fixture();
    fixture.create(this, def);

    if ((m_flags & e_activeFlag) == e_activeFlag) {
      BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;
      fixture.createProxy(broadPhase, m_xf);
    }

    fixture.m_next = m_fixtureList;
    m_fixtureList = fixture;
    ++m_fixtureCount;

    fixture.m_body = this;

    // Adjust mass properties if needed.
    if (fixture.m_density > 0.0f) {
      resetMassData();
    }

    // Let the world know we have a new fixture. This will cause new contacts
    // to be created at the beginning of the next time step.
    m_world.m_flags |= World.NEW_FIXTURE;

    return fixture;
  }
Beispiel #3
0
  /**
   * Notification that this body is being added to the world
   *
   * @param world The world this body is being added to
   */
  void addToWorld(World world) {
    org.jbox2d.dynamics.World jboxWorld = world.getJBoxWorld();

    jboxBody = jboxWorld.createBody(jboxBodyDef);
    shape.createInBody(this);

    if (!staticBody) {
      jboxBody.setMassFromShapes();
    } else {
      jboxBody.m_type = org.jbox2d.dynamics.Body.e_staticType;
    }
  }
Beispiel #4
0
  private Body initPhysicsBody(World world, float x, float y) {
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyType.DYNAMIC;
    bodyDef.position = new Vec2(0, 0);
    Body body = world.createBody(bodyDef);

    PolygonShape shape = new PolygonShape();
    Transform fx = new Transform();
    fx.position.set(100f, 100f);
    shape.centroid(fx);

    shape.setAsBox(
        sprite.layer().width() * GameScreen.M_PER_PIXEL / 2,
        sprite.layer().height() * GameScreen.M_PER_PIXEL / 2);
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = shape;
    fixtureDef.density = 0.4f;
    fixtureDef.friction = 0.1f;
    fixtureDef.restitution = 0f;
    body.createFixture(fixtureDef);
    body.setLinearDamping(0.2f);
    body.setTransform(new Vec2(x, y), 0f);

    //        MassData md = body.getMassData();
    //        massD.center.set(2f, 0); body.setMassData(massD);

    return body;
  }
Beispiel #5
0
  /** 创建多边形物体 */
  private void createBody() {
    // 定义物体的形状是多边形形状
    PolygonShape shape = new PolygonShape();
    shape.set(vecs, edge);

    // 设置多边形物体的一些固定的物理属性
    FixtureDef fd = new FixtureDef();
    fd.shape = shape;
    // 固定设置参数
    fd.density = 5.0f; // 密度
    fd.friction = 0.3f; // 摩擦系数
    fd.restitution = restitution; // 恢复系数

    BodyDef bd = new BodyDef();
    bd.position.set(x, y);
    bd.type = BodyType.DYNAMIC;
    bd.angle = angle;
    bd.allowSleep = true;
    bd.setAwake(true);

    // 根据bodyDef创建物体到世界中
    body = world.createBody(bd);
    // 设置好物体的固定属性
    body.createFixture(fd);
  }
  public void update(GameContainer arg0, int arg1) throws SlickException {
    world.step(timeStep, velocityIterations, positionIterations);

    Fixture fa = cDetect.fa;
    Fixture fb = cDetect.fb;

    if (fa != null && fb != null) {

      player1.checkDeleteFixture(fa, fb);
      player2.checkDeleteFixture(fa, fb);

      asteroids.damageAsteroid(fa);
      asteroids.damageAsteroid(fb);
    }

    player1.batteryLeft = 100f;

    player1.calcForce(input, arg1, player2.player.getPosition());
    player2.calcForceCPU(
        player1.player.getPosition(), asteroids.asteroids, new ArrayList<Vec2>(), arg1);

    player1.checkDeath();
    player2.checkDeath();

    if (player1.dead) {
      over = true;
    }
    if (player2.dead) {
      winner += 1; // In this case, winner will be used to determine score
      world.destroyBody(player2.player);
      player2 = new ShipCPU(player2Ship, world, tr, level);
      float jX = tr.width / tr.xscale;
      float jY = tr.height / tr.yscale;

      float max = jY / 2 - 15;
      float min = -jY / 2 + 15;
      float p2Y = (float) (Math.random() * (max - min) + min);

      player2.player.setTransform(new Vec2(jX / 2 - 15, p2Y), (float) Math.PI / 2);
    }

    if (input.isKeyDown(Input.KEY_ESCAPE)) {
      over = true;
    }
  }
Beispiel #7
0
  /**
   * Set the mass properties to override the mass properties of the fixtures. Note that this changes
   * the center of mass position. Note that creating or destroying fixtures can also alter the mass.
   * This function has no effect if the body isn't dynamic.
   *
   * @param massData the mass properties.
   */
  public final void setMassData(MassData massData) {
    // TODO_ERIN adjust linear velocity and torque to account for movement of center.
    assert (m_world.isLocked() == false);
    if (m_world.isLocked() == true) {
      return;
    }

    if (m_type != BodyType.DYNAMIC) {
      return;
    }

    m_invMass = 0.0f;
    m_I = 0.0f;
    m_invI = 0.0f;

    m_mass = massData.mass;
    if (m_mass <= 0.0f) {
      m_mass = 1f;
    }

    m_invMass = 1.0f / m_mass;

    if (massData.I > 0.0f && (m_flags & e_fixedRotationFlag) == 0) {
      m_I = massData.I - m_mass * Vec2.dot(massData.center, massData.center);
      assert (m_I > 0.0f);
      m_invI = 1.0f / m_I;
    }

    final Vec2 oldCenter = m_world.getPool().popVec2();
    // Move center of mass.
    oldCenter.set(m_sweep.c);
    m_sweep.localCenter.set(massData.center);
    // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter);
    Transform.mulToOut(m_xf, m_sweep.localCenter, m_sweep.c0);
    m_sweep.c.set(m_sweep.c0);

    // Update center of mass velocity.
    // m_linearVelocity += Cross(m_angularVelocity, m_sweep.c - oldCenter);
    final Vec2 temp = m_world.getPool().popVec2();
    temp.set(m_sweep.c).subLocal(oldCenter);
    Vec2.crossToOut(m_angularVelocity, temp, temp);
    m_linearVelocity.addLocal(temp);

    m_world.getPool().pushVec2(2);
  }
 private static void fractureCheck(
     final Fixture f1, final Fixture f2, final float iml, World w, Contact contact, int i) {
   materials.clear();
   for (Material m = f1.m_material; m != null; m = m.m_fragments) {
     if (materials.contains(m)) {
       return;
     }
     if (m.m_rigidity < iml) {
       f1.m_body.m_fractureTransformUpdate = f2.m_body.m_fractureTransformUpdate = false;
       if (f1.m_body.m_massArea > Material.MINMASSDESCTRUCTION) {
         WorldManifold wm = new WorldManifold();
         contact.getWorldManifold(wm); // vola sa iba raz
         w.addFracture(new Fracture(f1, f2, m, contact, iml, new Vec2(wm.points[i])));
       } else if (f1.m_body.m_type != BodyType.DYNAMIC) {
         w.addFracture(new Fracture(f1, f2, m, null, 0, null));
       }
     }
     materials.add(m);
   }
 }
Beispiel #9
0
  /**
   * Set the position of the body's origin and rotation. This breaks any contacts and wakes the
   * other bodies. Manipulating a body's transform may cause non-physical behavior.
   *
   * @param position the world position of the body's local origin.
   * @param angle the world rotation in radians.
   */
  public final void setTransform(Vec2 position, float angle) {
    assert (m_world.isLocked() == false);
    if (m_world.isLocked() == true) {
      return;
    }

    m_xf.R.set(angle);
    m_xf.position.set(position);

    // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter);
    Transform.mulToOut(m_xf, m_sweep.localCenter, m_sweep.c0);
    m_sweep.c.set(m_sweep.c0);

    m_sweep.a0 = m_sweep.a = angle;

    BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;
    for (Fixture f = m_fixtureList; f != null; f = f.m_next) {
      f.synchronize(broadPhase, m_xf, m_xf);
    }

    m_world.m_contactManager.findNewContacts();
  }
  public Planetoid(Sprite s, BodyDef bodyDef, World world, float mass, float forceFactor) {

    this.sprite = s;
    this.pBody = world.createBody(bodyDef);

    CircleShape circle = new CircleShape();

    circle.m_radius = this.sprite.getWidth() / Globals.PHYS_RATIO / Globals.magicBoundRatio;

    FixtureDef fixDef = new FixtureDef();

    fixDef.shape = circle;

    pBody.createFixture(fixDef);
    pBody.m_mass = mass;

    this.forceFactor = forceFactor;
  }
Beispiel #11
0
  @Override
  Body initPhysicsBody(World world, float x, float y, float width, float height, float angle) {
    FixtureDef fixtureDef = new FixtureDef();
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyType.DYNAMIC;
    bodyDef.position = new Vec2(0, 0);
    Body body = world.createBody(bodyDef);

    CircleShape circleShape = new CircleShape();
    circleShape.m_radius = RADIUS;
    fixtureDef.shape = circleShape;
    fixtureDef.density = 0.4f;
    fixtureDef.friction = 1f;
    fixtureDef.restitution = 0.0f;
    circleShape.m_p.set(0, 0);
    body.createFixture(fixtureDef);
    //        body.setLinearDamping(0.2f);
    body.setTransform(new Vec2(x, y), angle);
    return body;
  }
Beispiel #12
0
  public void initWorld() {
    Vec2 gravity = new Vec2(0.0f, 9.8f);
    world = new World(gravity);

    // ground
    FixtureDef groundFixtureDef = new FixtureDef();
    PolygonShape groundShape = new PolygonShape();
    groundShape.setAsBox(20f, 0.1f);
    groundFixtureDef.shape = groundShape;
    groundFixtureDef.density = 25.0f;
    groundFixtureDef.filter = new Filter();
    groundFixtureDef.filter.categoryBits = 0x0001;

    BodyDef groundBodyDef = new BodyDef();
    groundBodyDef.position = new Vec2(0.0f, 3f);
    groundBodyDef.angle = 0.0f;
    groundBodyDef.type = BodyType.STATIC;

    groundBody = world.createBody(groundBodyDef);
    groundFixture = groundBody.createFixture(groundFixtureDef);
  }
  public void init(GameContainer container) throws SlickException {
    if (container instanceof AppGameContainer) {
      app = (AppGameContainer) container;
    }

    over = false;

    input = container.getInput();

    Vec2 gravity = new Vec2(0.0f, 0.0f);
    world = new World(gravity, true);

    player1 = new ShipBuild(player1Ship, world, tr);
    player2 = new ShipCPU(player2Ship, world, tr, level); // thats the time in ms for shooting

    float jX = tr.width / tr.xscale;
    float jY = tr.height / tr.yscale;

    float max = jY / 2 - 15;
    float min = -jY / 2 + 15;

    asteroids = new AsteroidSpawner(world, tr);
    asteroids.genAsteroids(jX / 2 - 40, max - 25);

    float p1Y = (float) (Math.random() * (max - min) + min);
    float p2Y = (float) (Math.random() * (max - min) + min);
    player1.player.setTransform(new Vec2(-jX / 2 + 15, p1Y), 3 * (float) Math.PI / 2);
    player2.player.setTransform(new Vec2(jX / 2 - 15, p2Y), (float) Math.PI / 2);

    player1.inputForward = Input.KEY_W; // E;
    player1.inputLeft = Input.KEY_A; // W;
    player1.inputRight = Input.KEY_D; // R;
    player1.inputShoot = Input.KEY_SPACE; // A;
    player1.inputBackward = Input.KEY_S;

    cDetect = new CollideTest(player1, player2, world);

    world.setContactListener(cDetect);
  }
Beispiel #14
0
  /**
   * Destroy a fixture. This removes the fixture from the broad-phase and destroys all contacts
   * associated with this fixture. This will automatically adjust the mass of the body if the body
   * is dynamic and the fixture has positive density. All fixtures attached to a body are implicitly
   * destroyed when the body is destroyed.
   *
   * @param fixture the fixture to be removed.
   * @warning This function is locked during callbacks.
   */
  public final void destroyFixture(Fixture fixture) {
    assert (m_world.isLocked() == false);
    if (m_world.isLocked() == true) {
      return;
    }

    assert (fixture.m_body == this);

    // Remove the fixture from this body's singly linked list.
    assert (m_fixtureCount > 0);
    Fixture node = m_fixtureList;
    Fixture last = null; // java change
    boolean found = false;
    while (node != null) {
      if (node == fixture) {
        node = fixture.m_next;
        found = true;
        break;
      }
      last = node;
      node = node.m_next;
    }

    // You tried to remove a shape that is not attached to this body.
    assert (found);

    // java change, remove it from the list
    if (last == null) {
      m_fixtureList = fixture.m_next;
    } else {
      last.m_next = fixture.m_next;
    }

    // Destroy any contacts associated with the fixture.
    ContactEdge edge = m_contactList;
    while (edge != null) {
      Contact c = edge.contact;
      edge = edge.next;

      Fixture fixtureA = c.getFixtureA();
      Fixture fixtureB = c.getFixtureB();

      if (fixture == fixtureA || fixture == fixtureB) {
        // This destroys the contact and removes it from
        // this body's contact list.
        m_world.m_contactManager.destroy(c);
      }
    }

    if ((m_flags & e_activeFlag) == e_activeFlag) {
      assert (fixture.m_proxy != null);
      BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;
      fixture.destroyProxy(broadPhase);
    } else {
      assert (fixture.m_proxy == null);
    }

    fixture.destroy();
    fixture.m_body = null;
    fixture.m_next = null;
    fixture = null;

    --m_fixtureCount;

    // Reset the mass data.
    resetMassData();
  }
Beispiel #15
0
 public void step(float step_speed) {
   world.step(step_speed, 10, 10);
 }
Beispiel #16
0
  /**
   * This resets the mass properties to the sum of the mass properties of the fixtures. This
   * normally does not need to be called unless you called setMassData to override the mass and you
   * later want to reset the mass.
   */
  public final void resetMassData() {
    // Compute mass data from shapes. Each shape has its own density.
    m_mass = 0.0f;
    m_invMass = 0.0f;
    m_I = 0.0f;
    m_invI = 0.0f;
    m_sweep.localCenter.setZero();

    // Static and kinematic bodies have zero mass.
    if (m_type == BodyType.STATIC || m_type == BodyType.KINEMATIC) {
      // m_sweep.c0 = m_sweep.c = m_xf.position;
      m_sweep.c.set(m_xf.position);
      m_sweep.c0.set(m_xf.position);
      return;
    }

    assert (m_type == BodyType.DYNAMIC);

    // Accumulate mass over all fixtures.
    final Vec2 center = m_world.getPool().popVec2();
    center.setZero();
    final Vec2 temp = m_world.getPool().popVec2();
    final MassData massData = pmd;
    for (Fixture f = m_fixtureList; f != null; f = f.m_next) {
      if (f.m_density == 0.0f) {
        continue;
      }
      f.getMassData(massData);
      m_mass += massData.mass;
      // center += massData.mass * massData.center;
      temp.set(massData.center).mulLocal(massData.mass);
      center.addLocal(temp);
      m_I += massData.I;
    }

    // Compute center of mass.
    if (m_mass > 0.0f) {
      m_invMass = 1.0f / m_mass;
      center.mulLocal(m_invMass);
    } else {
      // Force all dynamic bodies to have a positive mass.
      m_mass = 1.0f;
      m_invMass = 1.0f;
    }

    if (m_I > 0.0f && (m_flags & e_fixedRotationFlag) == 0) {
      // Center the inertia about the center of mass.
      m_I -= m_mass * Vec2.dot(center, center);
      assert (m_I > 0.0f);
      m_invI = 1.0f / m_I;
    } else {
      m_I = 0.0f;
      m_invI = 0.0f;
    }

    Vec2 oldCenter = m_world.getPool().popVec2();
    // Move center of mass.
    oldCenter.set(m_sweep.c);
    m_sweep.localCenter.set(center);
    // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter);
    Transform.mulToOut(m_xf, m_sweep.localCenter, m_sweep.c0);
    m_sweep.c.set(m_sweep.c0);

    // Update center of mass velocity.
    // m_linearVelocity += Cross(m_angularVelocity, m_sweep.c - oldCenter);
    temp.set(m_sweep.c).subLocal(oldCenter);
    Vec2.crossToOut(m_angularVelocity, temp, temp);
    m_linearVelocity.addLocal(temp);

    m_world.getPool().pushVec2(3);
  }
Beispiel #17
0
 /**
  * Notification that this body is being removed from the world
  *
  * @param world The world this body is being removed from
  */
 void removeFromWorld(World world) {
   userData = null;
   org.jbox2d.dynamics.World jboxWorld = world.getJBoxWorld();
   jboxWorld.destroyBody(jboxBody);
 }
Beispiel #18
0
  private void addWorldContactListener(World world) {
    world.setContactListener(
        new ContactListener() {
          public void result(ContactResult point) {
            //				System.out.println("Result contact");
          }
          // @Override
          public void remove(ContactPoint point) {
            //				System.out.println("remove contact");
          }
          // @Override
          public void persist(ContactPoint point) {
            //				System.out.println("persist contact");
          }
          // @Override
          public void add(ContactPoint point) {
            //				/*
            Shape shape1 = point.shape1;
            Shape shape2 = point.shape2;
            final Body body1 = shape1.getBody();
            final Body body2 = shape2.getBody();
            Object userData1 = body1.getUserData();
            Object userData2 = body2.getUserData();

            if (userData1 instanceof IPhysicsComponent
                && userData2 instanceof IPhysicsComponent) { // Check for ball/star collision
              IPhysicsComponent physObj1 = (IPhysicsComponent) userData1;
              IPhysicsComponent physObj2 = (IPhysicsComponent) userData2;
              //					System.out.println("Collided: " + mt4jObj1 + " with " + mt4jObj2);
              if (physObj1 instanceof MTComponent && physObj2 instanceof MTComponent) {
                MTComponent comp1 = (MTComponent) physObj1;
                MTComponent comp2 = (MTComponent) physObj2;

                // Check if one of the components is the BALL
                MTComponent ball = isHit("ball", comp1, comp2);
                final MTComponent theBall = ball;

                // Check if one of the components is the GOAL
                MTComponent goal1 = isHit("goal1", comp1, comp2);
                MTComponent goal2 = isHit("goal2", comp1, comp2);

                // Check if a puck was involved
                MTComponent bluePuck = isHit("blue", comp1, comp2);
                MTComponent redPuck = isHit("red", comp1, comp2);

                // Check if a border was hit
                MTComponent border = null;
                if (comp1.getName() != null && comp1.getName().startsWith("border")) {
                  border = comp1;
                } else if (comp2.getName() != null && comp2.getName().startsWith("border")) {
                  border = comp2;
                }

                if (ball != null) {
                  // CHECK IF BALL HIT A PADDLE
                  if (enableSound && (bluePuck != null || redPuck != null)) {
                    //								System.out.println("PUCK HIT BALL!");
                    /*
                    triggerSound(paddleHit);
                    */
                  }

                  // Check if BALL HIT A GOAL
                  if (goal1 != null || goal2 != null) {
                    // BALL HIT A GOAL
                    if (goal1 != null) {
                      System.out.println("GOAL FOR PLAYER 2!");
                      scorePlayer2++;
                    } else if (goal2 != null) {
                      System.out.println("GOAL FOR PLAYER 1!");
                      scorePlayer1++;
                    }

                    // Update scores
                    updateScores();
                    // Play goal sound
                    //								triggerSound(goalHit);

                    if (scorePlayer1 >= 15 || scorePlayer2 >= 15) {
                      reset();
                    } else {

                      // Reset ball
                      if (theBall.getUserData("resetted")
                          == null) { // To make sure that we call destroy only once
                        theBall.setUserData("resetted", true);
                        app.invokeLater(
                            new Runnable() {
                              public void run() {
                                IPhysicsComponent a = (IPhysicsComponent) theBall;
                                a.getBody()
                                    .setXForm(
                                        new Vec2(
                                            getMTApplication().width / 2f / scale,
                                            getMTApplication().height / 2f / scale),
                                        a.getBody().getAngle());
                                //											a.getBody().setLinearVelocity(new Vec2(0,0));
                                a.getBody()
                                    .setLinearVelocity(
                                        new Vec2(
                                            ToolsMath.getRandom(-8, 8),
                                            ToolsMath.getRandom(-8, 8)));
                                a.getBody().setAngularVelocity(0);
                                theBall.setUserData("resetted", null);
                              }
                            });
                      }
                    }
                  }

                  // If ball hit border Play sound
                  if (enableSound && border != null) {
                    /*
                    triggerSound(wallHit);
                    */
                  }
                }
              }
            } else { // if at lest one if the colliding bodies' userdata is not a physics shape

            }
            //				*/
          }
        });
  }
 public void newBody(BodyDef bodyDef, World world) {
   this.pBody = world.createBody(bodyDef);
 }
  /**
   * Rozbije objekt. Upravi objekt world tak, ze vymaze triesteny objekt a nahradi ho fragmentami na
   * zaklade nastaveneho materialu a clenskych premennych.
   *
   * @param dt casova dlzka framu
   */
  public void smash(float dt) {
    if (contact == null) { // riesi sa staticky prvok, ktory ma priliz maly obsah
      b1.setType(BodyType.DYNAMIC);
      return;
    }

    World w = b1.m_world;
    Shape s = f1.m_shape;
    Polygon p = f1.m_polygon;

    if (p == null) {
      switch (s.m_type) {
        case POLYGON:
          PolygonShape ps = (PolygonShape) s;
          Vec2[] vertices = ps.m_vertices;
          p = new Polygon();
          for (int i = 0; i < ps.m_count; ++i) {
            p.add(vertices[ps.m_count - i - 1]);
          }
          break;
        case CIRCLE:
          CircleShape cs = (CircleShape) s;
          p = new Polygon();
          float radius = cs.m_radius;

          double u = Math.PI * 2 / CIRCLEVERTICES;
          radius =
              (float) Math.sqrt(u / Math.sin(u))
                  * radius; // upravim radius tak, aby bola zachovana velkost obsahu

          Vec2 center = cs.m_p;
          for (int i = 0; i < CIRCLEVERTICES; ++i) {
            double j = u * i; // uhol
            float sin = (float) Math.sin(j);
            float cos = (float) Math.cos(j);
            Vec2 v = new Vec2(sin, cos).mulLocal(radius).addLocal(center);
            p.add(v);
          }
          break;
        default:
          throw new RuntimeException("Dany typ tvaru nepodporuje stiepenie");
      }
    }

    float mConst = f1.m_material.m_rigidity / normalImpulse; // sila v zavislosti na pevnosti telesa

    boolean fixA = f1 == contact.m_fixtureA; // true, ak f2 je v objekte contact ako m_fixtureA
    float oldAngularVelocity =
        fixA ? contact.m_angularVelocity_bodyA : contact.m_angularVelocity_bodyB;
    Vec2 oldLinearVelocity = fixA ? contact.m_linearVelocity_bodyA : contact.m_linearVelocity_bodyB;
    b1.setAngularVelocity(
        (b1.m_angularVelocity - oldAngularVelocity) * mConst + oldAngularVelocity);
    b1.setLinearVelocity(
        b1.m_linearVelocity.sub(oldLinearVelocity).mulLocal(mConst).addLocal(oldLinearVelocity));
    if (!w.isFractured(f2)
        && b2.m_type == BodyType.DYNAMIC
        && !b2.m_fractureTransformUpdate) { // ak sa druhy objekt nerozbija, tak sa jej nahodia
      // povodne hodnoty (TREBA MODIFIKOVAT POHYB OBJEKTU,
      // KTORY SPOSOBUJE ROZPAD)
      oldAngularVelocity =
          !fixA ? contact.m_angularVelocity_bodyA : contact.m_angularVelocity_bodyB;
      oldLinearVelocity = !fixA ? contact.m_linearVelocity_bodyA : contact.m_linearVelocity_bodyB;
      b2.setAngularVelocity(
          (b2.m_angularVelocity - oldAngularVelocity) * mConst + oldAngularVelocity);
      b2.setLinearVelocity(
          b2.m_linearVelocity.sub(oldLinearVelocity).mulLocal(mConst).addLocal(oldLinearVelocity));
      b2.setTransform(
          b2.m_xf0.p.add(b2.m_linearVelocity.mul(dt)),
          b2.m_xf0.q.getAngle()); // osetruje jbox2d od posuvania telesa pri rieseni kolizie
      b2.m_fractureTransformUpdate = true;
    }

    Vec2 localPoint = Transform.mulTrans(b1.m_xf, point);
    Vec2 b1Vec = b1.getLinearVelocityFromWorldPoint(point);
    Vec2 b2Vec = b2.getLinearVelocityFromWorldPoint(point);
    Vec2 localVector = b2Vec.subLocal(b1Vec);

    localVector.mulLocal(dt);
    Polygon[] fragment;
    try {
      fragment = m.split(p, localPoint, localVector, normalImpulse); // rodeli to
    } catch (RuntimeException ex) {
      return;
    }

    if (fragment.length == 1) { // nerozbilo to na ziadne fragmenty
      return;
    }

    // definuje tela fragmentov - tie maju vsetky rovnaku definiciu (preberaju parametre z povodneho
    // objektu)
    BodyDef bodyDef = new BodyDef();
    bodyDef.position.set(b1.m_xf.p); // pozicia
    bodyDef.angle = b1.m_xf.q.getAngle(); // otocenie
    bodyDef.fixedRotation = b1.isFixedRotation();
    bodyDef.angularDamping = b1.m_angularDamping;
    bodyDef.allowSleep = b1.isSleepingAllowed();

    FixtureDef fd = new FixtureDef();
    fd.friction = f1.m_friction; // trenie
    fd.restitution = f1.m_restitution; // odrazivost
    fd.isSensor = f1.m_isSensor;
    fd.density = f1.m_density;

    // odstrani fragmentacne predmety/cele teleso
    ArrayList<Fixture> fixtures = new ArrayList<>();
    if (f1.m_polygon != null) {
      for (Fixture f = b1.m_fixtureList; f != null; f = f.m_next) {
        if (f.m_polygon == f1.m_polygon) {
          fixtures.add(f);
        }
      }
    } else {
      fixtures.add(f1);
    }

    for (Fixture f : fixtures) {
      b1.destroyFixture(f);
    }

    if (b1.m_fixtureCount == 0) {
      w.destroyBody(b1);
    }

    // prida fragmenty do simulacie
    MyList<Body> newbodies = new MyList<>();
    for (Polygon pg : fragment) { // vytvori tela, prida fixtury, poriesi konvexnu dekompoziciu
      if (pg.isCorrect()) {
        if (pg instanceof Fragment) {
          Polygon[] convex = pg.convexDecomposition();
          bodyDef.type = BodyType.DYNAMIC;
          for (Polygon pgx : convex) {
            Body f_body = w.createBody(bodyDef);
            pgx.flip();
            PolygonShape ps = new PolygonShape();
            ps.set(pgx.getArray(), pgx.size());
            fd.shape = ps;
            fd.polygon = null;
            fd.material = f1.m_material.m_fragments; // rekurzivne stiepenie

            f_body.createFixture(fd);
            f_body.setAngularVelocity(b1.m_angularVelocity);
            f_body.setLinearVelocity(b1.getLinearVelocityFromLocalPoint(f_body.getLocalCenter()));
            newbodies.add(f_body);
          }

        } else {
          fd.material = f1.m_material.m_fragments; // rekurzivne stiepenie
          bodyDef.type = b1.getType();
          Body f_body = w.createBody(bodyDef);
          PolygonFixture pf = new PolygonFixture(pg);

          f_body.createFixture(pf, fd);
          f_body.setLinearVelocity(b1.getLinearVelocityFromLocalPoint(f_body.getLocalCenter()));
          f_body.setAngularVelocity(b1.m_angularVelocity);
          newbodies.add(f_body);
        }
      }
    }

    // zavola sa funkcia z fraction listeneru (pokial je nadefinovany)
    FractureListener fl = w.getContactManager().m_fractureListener;
    if (fl != null) {
      fl.action(m, normalImpulse, newbodies);
    }
  }
Beispiel #21
0
 public void destroyBody() {
   world.destroyBody(getBody());
 }
  public void start() {

    Vec2 gravity = new Vec2(0, 0);
    World world = new World(gravity);
    BodyDef groundBodyDef = new BodyDef();
    groundBodyDef.position.set(0, -25);
    Body groundBody = world.createBody(groundBodyDef);
    PolygonShape groundBox = new PolygonShape();
    groundBox.setAsBox(900, 10);
    groundBody.createFixture(groundBox, 0);

    // Dynamic Body
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyType.DYNAMIC;
    bodyDef.position.set(0, 0);
    Body body = world.createBody(bodyDef);
    PolygonShape dynamicBox = new PolygonShape();
    dynamicBox.setAsBox(12, 12);
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = dynamicBox;
    fixtureDef.density = 1f;
    fixtureDef.friction = 0.3f;
    body.createFixture(fixtureDef);

    // Setup world
    float timeStep = 1.0f / 60.0f;
    int velocityIterations = 6;
    int positionIterations = 2;
    body.setLinearVelocity(new Vec2(15.0f, -15.0f));
    body.setLinearDamping(2f);
    Vec2 f = body.getWorldVector(new Vec2(0.0f, -30.0f));
    Vec2 p = body.getWorldPoint(body.getLocalCenter().add(new Vec2(-.2f, 0f)));
    // body.applyForce(new Vec2(-200,-200),new Vec2(-200,200));

    try {
      Display.setDisplayMode(new DisplayMode(screen_width, screen_height));
      Display.create();
    } catch (LWJGLException e) {
      e.printStackTrace();
      System.exit(0);
    }

    lastFPS = getTime();

    // standardBall[0] = new Ball(400,200,0,12);
    // standardBall[1] = new Ball(100,210,2,12);
    // standardBall[0].addImpulse(-10,0);

    standardBall[0] = new Ball(200, 300, 0, 12);
    standardBall[1] = new Ball(415, 100, 2, 12);
    standardBall[0].addImpulse(10, -9.99f);

    standardBall[2] = new Ball(620, 270, 2, 12);
    standardBall[3] = new Ball(640, 290, 2, 12);
    standardBall[4] = new Ball(660, 310, 2, 12);
    standardBall[5] = new Ball(680, 330, 2, 12);

    standardBall[6] = new Ball(620, 230, 2, 12);
    standardBall[7] = new Ball(640, 210, 2, 12);
    standardBall[8] = new Ball(660, 190, 2, 12);
    standardBall[9] = new Ball(680, 170, 2, 12);

    standardBall[10] = new Ball(640, 250, 1, 12);
    standardBall[11] = new Ball(660, 230, 2, 12);
    standardBall[12] = new Ball(660, 270, 2, 12);
    standardBall[13] = new Ball(680, 290, 2, 12);
    standardBall[14] = new Ball(680, 210, 2, 12);
    standardBall[15] = new Ball(680, 250, 2, 12);

    standardTable = new Table(0, 0, 800, 400, 25, 15);

    // init OpenGL
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(0, 900, 0, 500, 1, -1);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);

    while (!Display.isCloseRequested()) {
      int delta = getDelta();
      world.step(timeStep, velocityIterations, positionIterations);
      Vec2 position = body.getPosition();
      float angle = body.getAngle();
      // System.out.printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);

      // Clear the screen and depth buffer
      GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

      standardTable.draw();

      for (int i = 0; i < NUMBER_OF_BALLS; i++) {
        standardBall[i].draw();
        standardBall[i].update(delta);
      }
      standardBall[0].setX((position.x * 20) + offset_x);
      standardBall[0].setY((position.y * 20) + offset_y);

      update(delta);

      Display.update();

      Display.sync(60);
    }
    Display.destroy();
  }