/**
   * Sets polygon with repeating texture region, the size of repeating grid is equal to region size
   *
   * @param region - region to repeat
   * @param vertices - cw vertices of polygon
   * @param density - number of regions per polygon width bound
   */
  public void setPolygon(TextureRegion region, float[] vertices, float density) {

    this.region = region;

    vertices = offset(vertices);

    Polygon polygon = new Polygon(vertices);
    Polygon tmpPoly = new Polygon();
    Polygon intersectionPoly = new Polygon();
    EarClippingTriangulator triangulator = new EarClippingTriangulator();

    int idx;

    Rectangle boundRect = polygon.getBoundingRectangle();

    if (density == -1) density = boundRect.getWidth() / region.getRegionWidth();

    float regionAspectRatio = (float) region.getRegionHeight() / (float) region.getRegionWidth();
    cols = (int) (Math.ceil(density));
    gridWidth = boundRect.getWidth() / density;
    gridHeight = regionAspectRatio * gridWidth;
    rows = (int) Math.ceil(boundRect.getHeight() / gridHeight);

    for (int col = 0; col < cols; col++) {
      for (int row = 0; row < rows; row++) {
        float[] verts = new float[8];
        idx = 0;
        verts[idx++] = col * gridWidth;
        verts[idx++] = row * gridHeight;
        verts[idx++] = (col) * gridWidth;
        verts[idx++] = (row + 1) * gridHeight;
        verts[idx++] = (col + 1) * gridWidth;
        verts[idx++] = (row + 1) * gridHeight;
        verts[idx++] = (col + 1) * gridWidth;
        verts[idx] = (row) * gridHeight;
        tmpPoly.setVertices(verts);

        Intersector.intersectPolygons(polygon, tmpPoly, intersectionPoly);
        verts = intersectionPoly.getVertices();
        if (verts.length > 0) {
          parts.add(snapToGrid(verts));
          ShortArray arr = triangulator.computeTriangles(verts);
          indices.add(arr.toArray());
        } else {
          // adding null for key consistancy, needed to get col/row from key
          // the other alternative is to make parts - IntMap<FloatArray>
          parts.add(null);
        }
      }
    }

    buildVertices();
  }
  // TODO: Refactor into multiple functions
  @Override
  public Entity buildEntity() {
    Entity player = new Entity();

    // Define the body
    BodyDef playerBody = new BodyDef();
    playerBody.type = BodyDef.BodyType.DynamicBody;
    playerBody.position.set(0, 0);

    // Create the components
    PhysicsComponent p = new PhysicsComponent(physicsWorld.createBody(playerBody), player);
    RenderComponent r = new RenderComponent();
    KeyboardInputComponent i = new KeyboardInputComponent();
    MoveAction m = new MoveAction();

    // Properties for the components
    Polygon sprite =
        new Polygon(
            new float[] {
              0, 5,
              3, -3,
              0, -2,
              -3, -3
            });

    PolygonShape fixShape = new PolygonShape();
    fixShape.set(sprite.getVertices());

    FixtureDef def = new FixtureDef();
    def.shape = fixShape;
    def.density = 1.2f;
    def.friction = 0f;
    def.restitution = 0.1f;

    // Apply properties
    p.physicsBody.createFixture(def);

    r.renderColor = Color.BLUE;
    r.sprite = sprite;

    m.lin_v = 5f;
    m.rot_v = 2f;

    // Add to player
    player.add(p);
    player.add(r);
    player.add(i);
    player.add(m);

    return player;
  }
  public static void deletePoint(Polygon poly, int index) {

    float verts[] = poly.getVertices();

    if (verts.length < 8) return;

    int length = verts.length;
    float destination[] = new float[length - 2];

    //		index = index * 2;

    System.arraycopy(verts, 0, destination, 0, index);
    System.arraycopy(verts, index + 2, destination, index, length - index - 2);

    poly.setVertices(destination);
  }
  public static void addPoint(Polygon poly, float x, float y, int index) {
    float verts[] = poly.getVertices();

    x -= poly.getX();
    y -= poly.getY();

    int length = verts.length;
    float destination[] = new float[length + 2];

    System.arraycopy(verts, 0, destination, 0, index);
    destination[index] = x;
    destination[index + 1] = y;
    System.arraycopy(verts, index, destination, index + 2, length - index);

    poly.setVertices(destination);
  }
 public TouchableEntity getTouchableEntity(AgentEntity agentEntity) {
   TouchableEntity touchableEntity = new TouchableEntity();
   DamageEffect damageEffect = new DamageEffect();
   damageEffect.setDamage(damage);
   damageEffect.setOriginatingAgent(agentEntity);
   touchableEntity.setCollisionPolygon(new Polygon(attackPolygon.getVertices()));
   Vector2 attackPosition = new Vector2();
   if (agentEntity.isFacingLeft()) {
     attackPosition
         .add(agentEntity.getLeftBoundingSide())
         .sub(attackPolygon.getBoundingRectangle().width, 0);
   } else {
     attackPosition.add(agentEntity.getRightBoundingSide());
   }
   touchableEntity.setPosition(attackPosition);
   return touchableEntity;
 }