@Override
  public void create() {
    mesh =
        new Mesh(
            true,
            3,
            0,
            new VertexAttribute(Usage.Position, 3, "a_Position"),
            new VertexAttribute(Usage.ColorPacked, 4, "a_Color"),
            new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));
    float c1 = Color.toFloatBits(255, 0, 0, 255);
    float c2 = Color.toFloatBits(255, 0, 0, 255);
    ;
    float c3 = Color.toFloatBits(0, 0, 255, 255);
    ;

    mesh.setVertices(
        new float[] {-0.5f, -0.5f, 0, c1, 0, 0, 0.5f, -0.5f, 0, c2, 1, 0, 0, 0.5f, 0, c3, 0.5f, 1});

    texture = new Texture(Gdx.files.internal("data/badlogic.jpg"));

    spriteBatch = new SpriteBatch();
    frameBuffer = new FrameBuffer(Format.RGB565, 128, 128, true);
    createShader(Gdx.graphics);
  }
  @Override
  public void create() {
    vbo =
        new VertexBufferObject(
            true,
            3,
            new VertexAttribute(VertexAttributes.Usage.Position, 2, "a_Position"),
            new VertexAttribute(VertexAttributes.Usage.TextureCoordinates, 2, "a_TexCoords"),
            new VertexAttribute(VertexAttributes.Usage.ColorPacked, 4, "a_Color"));
    float[] vertices =
        new float[] {
          -1,
          -1,
          0,
          0,
          Color.toFloatBits(1f, 0f, 0f, 1f),
          0,
          1,
          0.5f,
          1.0f,
          Color.toFloatBits(0f, 1f, 0f, 1f),
          1,
          -1,
          1,
          0,
          Color.toFloatBits(0f, 0f, 1f, 1f)
        };
    vbo.setVertices(vertices, 0, vertices.length);

    ibo = new IndexBufferObject(true, 3);
    ibo.setIndices(new short[] {0, 1, 2}, 0, 3);

    texture = new Texture(Gdx.files.internal("data/badlogic.jpg"));
  }
  @Override
  public void create() {
    String vertexShader =
        "attribute vec4 a_position;    \n"
            + "attribute vec4 a_color;\n"
            + "attribute vec2 a_texCoords;\n"
            + "varying vec4 v_color;"
            + "varying vec2 v_texCoords;"
            + "void main()                  \n"
            + "{                            \n"
            + "   v_color = vec4(a_color.x, a_color.y, a_color.z, 1); \n"
            + "   v_texCoords = a_texCoords; \n"
            + "   gl_Position =  a_position;  \n"
            + "}                            \n";
    String fragmentShader =
        "#ifdef GL_ES\n"
            + "precision mediump float;\n"
            + "#endif\n"
            + "varying vec4 v_color;\n"
            + "varying vec2 v_texCoords;\n"
            + "uniform sampler2D u_texture;\n"
            + "void main()                                  \n"
            + "{                                            \n"
            + "  gl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n"
            + "}";

    shader = new ShaderProgram(vertexShader, fragmentShader);
    vbo =
        new VertexBufferObject(
            true,
            3,
            new VertexAttribute(VertexAttributes.Usage.Position, 2, "a_position"),
            new VertexAttribute(VertexAttributes.Usage.TextureCoordinates, 2, "a_texCoords"),
            new VertexAttribute(VertexAttributes.Usage.ColorPacked, 4, "a_color"));
    float[] vertices =
        new float[] {
          -1,
          -1,
          0,
          0,
          Color.toFloatBits(1f, 0f, 0f, 1f),
          0,
          1,
          0.5f,
          1.0f,
          Color.toFloatBits(0f, 1f, 0f, 1f),
          1,
          -1,
          1,
          0,
          Color.toFloatBits(0f, 0f, 1f, 1f)
        };
    vbo.setVertices(vertices, 0, vertices.length);
    indices = new IndexBufferObject(3);
    indices.setIndices(new short[] {0, 1, 2}, 0, 3);

    texture = new Texture(Gdx.files.internal("data/badlogic.jpg"));
  }
Beispiel #4
0
  public void drawTriangle(
      int x, int y, float w, float h, double rotation, double speed, double color, double puls) {

    if (once == 0) {
      System.out.println("Triangle entered");
      // Image
      this.rectX = x;
      this.rectY = y;
      this.width = w;
      this.height = h;

      // Rotation purposes
      originX = x;
      originY = y;

      // Mesh Purposes
      float colour = Color.toFloatBits(0, 0, 0, 255); // default is black
      if (color == 1) {
        colour = Color.toFloatBits(255, 255, 255, 255); // set to white
      }
      float z = 0;
      float[] vertices = {x, y, z, colour, x, y, z, colour, x, y, z, colour};
      float[] verticesTri = {
        x, y, x, y, x, y,
      };
      this.verticesMesh = vertices;
      this.verticesPoly = verticesTri;

      this.speed = speed;
      this.rotation = rotation;
      this.color = color;
      this.pulsating = puls;

      once++;
    }

    // Triangle Polygon
    poly();

    // Image
    rectX -= this.speed;
    rectY -= this.speed;
    width += this.speed * 2;
    height += this.speed * 2;

    // Update Indices once after poly()
    if (once < 10) {
      indices = Helper.earclip.computeTriangles(verticesPoly).toArray();
      once++;
    }
  }
Beispiel #5
0
 @Override
 public short vertex(Vector3 pos, Vector3 nor, Color col, Vector2 uv) {
   if (vindex >= Short.MAX_VALUE) throw new GdxRuntimeException("Too many vertices used");
   if (col == null && colorSet) col = color;
   if (pos != null) {
     vertex[posOffset] = pos.x;
     if (posSize > 1) vertex[posOffset + 1] = pos.y;
     if (posSize > 2) vertex[posOffset + 2] = pos.z;
   }
   if (nor != null && norOffset >= 0) {
     vertex[norOffset] = nor.x;
     vertex[norOffset + 1] = nor.y;
     vertex[norOffset + 2] = nor.z;
   }
   if (col != null) {
     if (colOffset >= 0) {
       vertex[colOffset] = col.r;
       vertex[colOffset + 1] = col.g;
       vertex[colOffset + 2] = col.b;
       if (colSize > 3) vertex[colOffset + 3] = col.a;
     } else if (cpOffset > 0) vertex[cpOffset] = col.toFloatBits(); // FIXME cache packed color?
   }
   if (uv != null && uvOffset >= 0) {
     vertex[uvOffset] = uv.x;
     vertex[uvOffset + 1] = uv.y;
   }
   vertices.addAll(vertex);
   return (short) (vindex++);
 }
  /** Builds final vertices with vertex attributes like coordinates, color and region u/v */
  private void buildVertices() {
    vertices.clear();
    for (int i = 0; i < parts.size; i++) {
      float verts[] = parts.get(i);
      if (verts == null) continue;

      float[] fullVerts = new float[5 * verts.length / 2];
      int idx = 0;

      int col = i / rows;
      int row = i % rows;

      for (int j = 0; j < verts.length; j += 2) {
        fullVerts[idx++] = verts[j] + offset.x + x;
        fullVerts[idx++] = verts[j + 1] + offset.y + y;

        fullVerts[idx++] = color.toFloatBits();

        float u = (verts[j] % gridWidth) / gridWidth;
        float v = (verts[j + 1] % gridHeight) / gridHeight;
        if (verts[j] == col * gridWidth) u = 0f;
        if (verts[j] == (col + 1) * gridWidth) u = 1f;
        if (verts[j + 1] == row * gridHeight) v = 0f;
        if (verts[j + 1] == (row + 1) * gridHeight) v = 1f;
        u = region.getU() + (region.getU2() - region.getU()) * u;
        v = region.getV() + (region.getV2() - region.getV()) * v;
        fullVerts[idx++] = u;
        fullVerts[idx++] = v;
      }
      vertices.add(fullVerts);
    }
    dirty = false;
  }
 /**
  * Sets light color
  *
  * <p>NOTE: you can also use colorless light with shadows, e.g. (0,0,0,1)
  *
  * @param newColor RGB set the color and Alpha set intensity
  * @see #setColor(float, float, float, float)
  */
 public void setColor(Color newColor) {
   if (newColor != null) {
     color.set(newColor);
   } else {
     color.set(DefaultColor);
   }
   colorF = color.toFloatBits();
   if (staticLight) dirty = true;
 }
 private float getColor(ColourDiffuse colourDiffuse) {
   String[] tokens = colourDiffuse.getValue().split(" ");
   if (tokens.length == 3)
     color.set(Float.valueOf(tokens[0]), Float.valueOf(tokens[1]), Float.valueOf(tokens[2]), 1);
   else
     color.set(
         Float.valueOf(tokens[0]),
         Float.valueOf(tokens[1]),
         Float.valueOf(tokens[2]),
         Float.valueOf(tokens[3]));
   return color.toFloatBits();
 }
Beispiel #9
0
    public void updateData(Transform transform) {
      Vector2 before;
      Vector2 vector;
      Vector2 after;
      for (int i = 0; i < vertices.length; i++) {
        before = vertices[i == 0 ? vertices.length - 1 : i - 1];
        vector = vertices[i].cpy();
        after = vertices[i == vertices.length - 1 ? 0 : i + 1];

        // Vector2D vec1 = new Vector2D(new Point2D(after.x, after.y), new Point2D(vector.x,
        // vector.y));
        // Vector2D vec2 = new Vector2D(new Point2D(before.x, before.y), new Point2D(vector.x,
        // vector.y));
        //
        // double a1 = vec1.getAngle();
        // double a2 = vec2.getAngle();
        // double diff = a1 - a2;
        // double angle = (a1 + a2) / 2.0;
        //
        // if (diff > 0) {
        // angle -= Math.PI;
        // }
        //
        // Vector2D sum = new Vector2D(Math.cos(angle) * 0.2, Math.sin(angle) * 0.2);
        // sum.normalize();
        //
        // sum = sum.times(0.04);
        //
        // Vector2 newPoint = new Vector2(vector.x + (float) sum.getX(), vector.y + (float)
        // sum.getY());
        //
        // vector = newPoint.cpy();

        transform.mul(vector);

        int dataIndex = i * 6;
        meshesData[dataIndex] = vector.x;
        meshesData[dataIndex + 1] = vector.y;
        meshesData[dataIndex + 2] = 0;
        meshesData[dataIndex + 3] = Color.toFloatBits(128, 128, 128, 255);
        meshesData[dataIndex + 4] = vertices[i].x / 8.0f + 0.5f;
        meshesData[dataIndex + 5] = 1.0f - (vertices[i].y / 8.0f + 0.5f);
      }
      mesh.setVertices(meshesData);
    }
Beispiel #10
0
 /**
  * Sets the color used to tint images when they are added to the SpriteBatch. Default is {@link
  * Color#WHITE}.
  */
 public void setColor(Color tint) {
   color = tint.toFloatBits();
 }
  public Boundary() {
    Vector2 point_1 =
        new Vector2(-SPACE_BOUNDARY_X - BOUNDARY_SIZE, SPACE_BOUNDARY_Y + BOUNDARY_SIZE);

    Vector2 point_2 =
        new Vector2(SPACE_BOUNDARY_X + BOUNDARY_SIZE, SPACE_BOUNDARY_Y + BOUNDARY_SIZE);

    Vector2 point_3 = new Vector2(SPACE_BOUNDARY_X + BOUNDARY_SIZE, SPACE_BOUNDARY_Y);

    Vector2 point_4 = new Vector2(-SPACE_BOUNDARY_X - BOUNDARY_SIZE, SPACE_BOUNDARY_Y);

    Vector2 point_5 = new Vector2(SPACE_BOUNDARY_X, SPACE_BOUNDARY_Y);

    Vector2 point_6 = new Vector2(SPACE_BOUNDARY_X + BOUNDARY_SIZE, -SPACE_BOUNDARY_Y);

    Vector2 point_7 = new Vector2(SPACE_BOUNDARY_X, -SPACE_BOUNDARY_Y);

    Vector2 point_8 = new Vector2(-SPACE_BOUNDARY_X - BOUNDARY_SIZE, -SPACE_BOUNDARY_Y);

    Vector2 point_9 =
        new Vector2(SPACE_BOUNDARY_X + BOUNDARY_SIZE, -SPACE_BOUNDARY_Y - BOUNDARY_SIZE);

    Vector2 point_10 =
        new Vector2(-SPACE_BOUNDARY_X - BOUNDARY_SIZE, -SPACE_BOUNDARY_Y - BOUNDARY_SIZE);

    Vector2 point_11 = new Vector2(-SPACE_BOUNDARY_X, SPACE_BOUNDARY_Y);

    Vector2 point_12 = new Vector2(-SPACE_BOUNDARY_X, -SPACE_BOUNDARY_Y);

    float border_colour = Color.toFloatBits(255, 0, 0, 255);

    meshes[0] =
        MeshFactory.square(
            point_1,
            border_colour,
            point_2,
            border_colour,
            point_3,
            border_colour,
            point_4,
            border_colour);

    meshes[1] =
        MeshFactory.square(
            point_5,
            border_colour,
            point_3,
            border_colour,
            point_6,
            border_colour,
            point_7,
            border_colour);

    meshes[2] =
        MeshFactory.square(
            point_8,
            border_colour,
            point_6,
            border_colour,
            point_9,
            border_colour,
            point_10,
            border_colour);

    meshes[3] =
        MeshFactory.square(
            point_4,
            border_colour,
            point_11,
            border_colour,
            point_12,
            border_colour,
            point_8,
            border_colour);
  }
  @Override
  public void renderTileLayer(TiledMapTileLayer layer) {

    final float color = Color.toFloatBits(1, 1, 1, layer.getOpacity());

    final int layerWidth = layer.getWidth();
    final int layerHeight = layer.getHeight();

    final float layerTileWidth = layer.getTileWidth() * unitScale;
    final float layerTileHeight = layer.getTileHeight() * unitScale;

    final float layerTileWidth25 = layerTileWidth * 0.25f;
    final float layerTileWidth50 = layerTileWidth * 0.50f;
    final float layerTileWidth75 = layerTileWidth * 0.75f;

    final float layerTileHeight50 = layerTileHeight * 0.50f;
    final float layerTileHeight150 = layerTileHeight * 1.50f;

    final int col1 = Math.max(0, (int) (((viewBounds.x - layerTileWidth25) / layerTileWidth75)));
    final int col2 =
        Math.min(
            layerWidth,
            (int) ((viewBounds.x + viewBounds.width + layerTileWidth75) / layerTileWidth75));

    final int row1 = Math.max(0, (int) ((viewBounds.y / layerTileHeight150)));
    final int row2 =
        Math.min(
            layerHeight,
            (int) ((viewBounds.y + viewBounds.height + layerTileHeight150) / layerTileHeight));

    final float[] vertices = this.vertices;

    for (int row = row1; row < row2; row++) {
      for (int col = col1; col < col2; col++) {

        float x = layerTileWidth75 * col;
        float y = (col % 2 == (yDown ? 0 : 1) ? 0 : layerTileHeight50) + (layerTileHeight * row);

        final TiledMapTileLayer.Cell cell = layer.getCell(col, row);
        if (cell == null) {
          x += layerTileWidth;
          continue;
        }
        final TiledMapTile tile = cell.getTile();
        if (tile != null) {
          if (tile instanceof AnimatedTiledMapTile) continue;

          final boolean flipX = cell.getFlipHorizontally();
          final boolean flipY = cell.getFlipVertically();
          final int rotations = cell.getRotation();

          TextureRegion region = tile.getTextureRegion();

          float x1 = x;
          float y1 = y;
          float x2 = x1 + region.getRegionWidth() * unitScale;
          float y2 = y1 + region.getRegionHeight() * unitScale;

          float u1 = region.getU();
          float v1 = region.getV2();
          float u2 = region.getU2();
          float v2 = region.getV();

          vertices[X1] = x1;
          vertices[Y1] = y1;
          vertices[C1] = color;
          vertices[U1] = u1;
          vertices[V1] = v1;

          vertices[X2] = x1;
          vertices[Y2] = y2;
          vertices[C2] = color;
          vertices[U2] = u1;
          vertices[V2] = v2;

          vertices[X3] = x2;
          vertices[Y3] = y2;
          vertices[C3] = color;
          vertices[U3] = u2;
          vertices[V3] = v2;

          vertices[X4] = x2;
          vertices[Y4] = y1;
          vertices[C4] = color;
          vertices[U4] = u2;
          vertices[V4] = v1;

          if (flipX) {
            float temp = vertices[U1];
            vertices[U1] = vertices[U3];
            vertices[U3] = temp;
            temp = vertices[U2];
            vertices[U2] = vertices[U4];
            vertices[U4] = temp;
          }
          if (flipY) {
            float temp = vertices[V1];
            vertices[V1] = vertices[V3];
            vertices[V3] = temp;
            temp = vertices[V2];
            vertices[V2] = vertices[V4];
            vertices[V4] = temp;
          }
          if (rotations == 2) {
            float tempU = vertices[U1];
            vertices[U1] = vertices[U3];
            vertices[U3] = tempU;
            tempU = vertices[U2];
            vertices[U2] = vertices[U4];
            vertices[U4] = tempU;
            float tempV = vertices[V1];
            vertices[V1] = vertices[V3];
            vertices[V3] = tempV;
            tempV = vertices[V2];
            vertices[V2] = vertices[V4];
            vertices[V4] = tempV;
            break;
          }
          spriteBatch.draw(region.getTexture(), vertices, 0, 20);
        }
      }
    }
  }
  @Override
  public void renderTileLayer(TiledMapTileLayer layer) {
    final Color batchColor = batch.getColor();
    final float color =
        Color.toFloatBits(
            batchColor.r, batchColor.g, batchColor.b, batchColor.a * layer.getOpacity());

    final int layerWidth = layer.getWidth();
    final int layerHeight = layer.getHeight();

    final float layerTileWidth = layer.getTileWidth() * unitScale;
    final float layerTileHeight = layer.getTileHeight() * unitScale;

    final float layerTileWidth50 = layerTileWidth * 0.50f;
    final float layerTileHeight50 = layerTileHeight * 0.50f;

    final int minX = Math.max(0, (int) (((viewBounds.x - layerTileWidth50) / layerTileWidth)));
    final int maxX =
        Math.min(
            layerWidth,
            (int)
                ((viewBounds.x + viewBounds.width + layerTileWidth + layerTileWidth50)
                    / layerTileWidth));

    final int minY = Math.max(0, (int) (((viewBounds.y - layerTileHeight) / layerTileHeight)));
    final int maxY =
        Math.min(
            layerHeight,
            (int) ((viewBounds.y + viewBounds.height + layerTileHeight) / layerTileHeight50));

    for (int y = maxY - 1; y >= minY; y--) {
      float offsetX = (y % 2 == 1) ? layerTileWidth50 : 0;
      for (int x = maxX - 1; x >= minX; x--) {
        final TiledMapTileLayer.Cell cell = layer.getCell(x, y);
        if (cell == null) continue;
        final TiledMapTile tile = cell.getTile();

        if (tile != null) {
          final boolean flipX = cell.getFlipHorizontally();
          final boolean flipY = cell.getFlipVertically();
          final int rotations = cell.getRotation();
          TextureRegion region = tile.getTextureRegion();

          float x1 = x * layerTileWidth - offsetX + tile.getOffsetX() * unitScale;
          float y1 = y * layerTileHeight50 + tile.getOffsetY() * unitScale;
          float x2 = x1 + region.getRegionWidth() * unitScale;
          float y2 = y1 + region.getRegionHeight() * unitScale;

          float u1 = region.getU();
          float v1 = region.getV2();
          float u2 = region.getU2();
          float v2 = region.getV();

          vertices[X1] = x1;
          vertices[Y1] = y1;
          vertices[C1] = color;
          vertices[U1] = u1;
          vertices[V1] = v1;

          vertices[X2] = x1;
          vertices[Y2] = y2;
          vertices[C2] = color;
          vertices[U2] = u1;
          vertices[V2] = v2;

          vertices[X3] = x2;
          vertices[Y3] = y2;
          vertices[C3] = color;
          vertices[U3] = u2;
          vertices[V3] = v2;

          vertices[X4] = x2;
          vertices[Y4] = y1;
          vertices[C4] = color;
          vertices[U4] = u2;
          vertices[V4] = v1;

          if (flipX) {
            float temp = vertices[U1];
            vertices[U1] = vertices[U3];
            vertices[U3] = temp;
            temp = vertices[U2];
            vertices[U2] = vertices[U4];
            vertices[U4] = temp;
          }

          if (flipY) {
            float temp = vertices[V1];
            vertices[V1] = vertices[V3];
            vertices[V3] = temp;
            temp = vertices[V2];
            vertices[V2] = vertices[V4];
            vertices[V4] = temp;
          }

          if (rotations != 0) {
            switch (rotations) {
              case Cell.ROTATE_90:
                {
                  float tempV = vertices[V1];
                  vertices[V1] = vertices[V2];
                  vertices[V2] = vertices[V3];
                  vertices[V3] = vertices[V4];
                  vertices[V4] = tempV;

                  float tempU = vertices[U1];
                  vertices[U1] = vertices[U2];
                  vertices[U2] = vertices[U3];
                  vertices[U3] = vertices[U4];
                  vertices[U4] = tempU;
                  break;
                }
              case Cell.ROTATE_180:
                {
                  float tempU = vertices[U1];
                  vertices[U1] = vertices[U3];
                  vertices[U3] = tempU;
                  tempU = vertices[U2];
                  vertices[U2] = vertices[U4];
                  vertices[U4] = tempU;
                  float tempV = vertices[V1];
                  vertices[V1] = vertices[V3];
                  vertices[V3] = tempV;
                  tempV = vertices[V2];
                  vertices[V2] = vertices[V4];
                  vertices[V4] = tempV;
                  break;
                }
              case Cell.ROTATE_270:
                {
                  float tempV = vertices[V1];
                  vertices[V1] = vertices[V4];
                  vertices[V4] = vertices[V3];
                  vertices[V3] = vertices[V2];
                  vertices[V2] = tempV;

                  float tempU = vertices[U1];
                  vertices[U1] = vertices[U4];
                  vertices[U4] = vertices[U3];
                  vertices[U3] = vertices[U2];
                  vertices[U2] = tempU;
                  break;
                }
            }
          }
          batch.draw(region.getTexture(), vertices, 0, 20);
        }
      }
    }
  }
/**
 * Light is data container for all the light parameters. When created lights are automatically added
 * to rayHandler and could be removed by calling {@link #remove()} and added manually by calling
 * {@link #add(RayHandler)}.
 *
 * <p>Implements {@link Disposable}
 *
 * @author kalle_h
 */
public abstract class Light implements Disposable {

  static final Color DefaultColor = new Color(0.75f, 0.75f, 0.5f, 0.75f);
  static final float zeroColorBits = Color.toFloatBits(0f, 0f, 0f, 0f);
  static final int MIN_RAYS = 3;

  protected final Color color = new Color();
  protected final Vector2 tmpPosition = new Vector2();

  protected RayHandler rayHandler;

  protected boolean active = true;
  protected boolean soft = true;
  protected boolean xray = false;
  protected boolean staticLight = false;
  protected boolean culled = false;
  protected boolean dirty = true;
  protected boolean ignoreBody = false;

  protected int rayNum;
  protected int vertexNum;

  protected float direction;
  protected float colorF;
  protected float softShadowLength = 2.5f;

  protected Mesh lightMesh;
  protected Mesh softShadowMesh;

  protected float segments[];
  protected float[] mx;
  protected float[] my;
  protected float[] f;
  protected int m_index = 0;

  /**
   * Creates new active light and automatically adds it to the specified {@link RayHandler}
   * instance.
   *
   * @param rayHandler not null instance of RayHandler
   * @param rays number of rays - more rays make light to look more realistic but will decrease
   *     performance, can't be less than MIN_RAYS
   * @param color light color
   * @param distance light distance (if applicable)
   * @param directionDegree direction in degrees (if applicable)
   */
  public Light(RayHandler rayHandler, int rays, Color color, float directionDegree) {
    rayHandler.lightList.add(this);
    this.rayHandler = rayHandler;
    setRayNum(rays);
    setColor(color);
    //		setDistance(distance); //TODO move to a factory method
    setDirection(directionDegree);
  }

  /** Updates this light */
  abstract void update();

  /** Render this light */
  abstract void render();

  /** Sets light direction */
  public abstract void setDirection(float directionDegree);

  /**
   * Attaches light to specified body
   *
   * @param body that will be automatically followed, note that the body rotation angle is taken
   *     into account for the light offset and direction calculations
   */
  public abstract void attachToBody(Body body);

  /**
   * @return attached body or {@code null}
   * @see #attachToBody(Body)
   */
  public abstract Body getBody();

  /**
   * Sets light starting position
   *
   * @see #setPosition(Vector2)
   */
  public abstract void setPosition(float x, float y);

  /**
   * Sets light starting position
   *
   * @see #setPosition(float, float)
   */
  public abstract void setPosition(Vector2 position);

  /** @return horizontal starting position of light in world coordinates */
  public abstract float getX();

  /** @return vertical starting position of light in world coordinates */
  public abstract float getY();

  /**
   * @return starting position of light in world coordinates
   *     <p>NOTE: changing this vector does nothing
   */
  public Vector2 getPosition() {
    return tmpPosition;
  }

  /**
   * Sets light color
   *
   * <p>NOTE: you can also use colorless light with shadows, e.g. (0,0,0,1)
   *
   * @param newColor RGB set the color and Alpha set intensity
   * @see #setColor(float, float, float, float)
   */
  public void setColor(Color newColor) {
    if (newColor != null) {
      color.set(newColor);
    } else {
      color.set(DefaultColor);
    }
    colorF = color.toFloatBits();
    if (staticLight) dirty = true;
  }

  /**
   * Sets light color
   *
   * <p>NOTE: you can also use colorless light with shadows, e.g. (0,0,0,1)
   *
   * @param r lights color red component
   * @param g lights color green component
   * @param b lights color blue component
   * @param a lights shadow intensity
   * @see #setColor(Color)
   */
  public void setColor(float r, float g, float b, float a) {
    color.set(r, g, b, a);
    colorF = color.toFloatBits();
    if (staticLight) dirty = true;
  }

  /** Adds light to specified RayHandler */
  public void add(RayHandler rayHandler) {
    this.rayHandler = rayHandler;
    if (active) {
      rayHandler.lightList.add(this);
    } else {
      rayHandler.disabledLights.add(this);
    }
  }

  /** Removes light from specified RayHandler and disposes it */
  public void remove() {
    remove(true);
  }

  /** Removes light from specified RayHandler and disposes it if requested */
  public void remove(boolean doDispose) {
    if (active) {
      rayHandler.lightList.removeValue(this, false);
    } else {
      rayHandler.disabledLights.removeValue(this, false);
    }
    rayHandler = null;
    if (doDispose) dispose();
  }

  /** Disposes all light resources */
  public void dispose() {
    lightMesh.dispose();
    softShadowMesh.dispose();
  }

  /** @return if this light is active */
  public boolean isActive() {
    return active;
  }

  /** Enables/disables this light update and rendering */
  public void setActive(boolean active) {
    if (active == this.active) return;

    this.active = active;
    if (rayHandler == null) return;

    if (active) {
      rayHandler.lightList.add(this);
      rayHandler.disabledLights.removeValue(this, true);
    } else {
      rayHandler.disabledLights.add(this);
      rayHandler.lightList.removeValue(this, true);
    }
  }

  /** @return if this light beams go through obstacles */
  public boolean isXray() {
    return xray;
  }

  /**
   * Enables/disables x-ray beams for this light
   *
   * <p>Enabling this will allow beams go through obstacles that reduce CPU burden of light about
   * 70%.
   *
   * <p>Use the combination of x-ray and non x-ray lights wisely
   */
  public void setXray(boolean xray) {
    this.xray = xray;
    if (staticLight) dirty = true;
  }

  /**
   * @return if this light is static
   *     <p>Static light do not get any automatic updates but setting any parameters will update it.
   *     Static lights are useful for lights that you want to collide with static geometry but
   *     ignore all the dynamic objects.
   */
  public boolean isStaticLight() {
    return staticLight;
  }

  /**
   * Enables/disables this light static behavior
   *
   * <p>Static light do not get any automatic updates but setting any parameters will update it.
   * Static lights are useful for lights that you want to collide with static geometry but ignore
   * all the dynamic objects
   *
   * <p>Reduce CPU burden of light about 90%
   */
  public void setStaticLight(boolean staticLight) {
    this.staticLight = staticLight;
    if (staticLight) dirty = true;
  }

  /** @return if tips of this light beams are soft */
  public boolean isSoft() {
    return soft;
  }

  /** Enables/disables softness on tips of this light beams */
  public void setSoft(boolean soft) {
    this.soft = soft;
    if (staticLight) dirty = true;
  }

  /**
   * @return softness value for beams tips
   *     <p>Default: {@code 2.5f}
   */
  public float getSoftShadowLength() {
    return softShadowLength;
  }

  /**
   * Sets softness value for beams tips
   *
   * <p>Default: {@code 2.5f}
   */
  public void setSoftnessLength(float softShadowLength) {
    this.softShadowLength = softShadowLength;
    if (staticLight) dirty = true;
  }

  /** @return current color of this light */
  public Color getColor() {
    return color;
  }

  /**
   * Checks if given point is inside of this light area
   *
   * @param x - horizontal position of point in world coordinates
   * @param y - vertical position of point in world coordinates
   */
  public boolean contains(float x, float y) {
    return false;
  }

  /**
   * Sets if the attached body fixtures should be ignored during raycasting
   *
   * @param flag - if {@code true} all the fixtures of attached body will be ignored and will not
   *     create any shadows for this light. By default is set to {@code false}.
   */
  public void setIgnoreAttachedBody(boolean flag) {
    ignoreBody = flag;
  }

  /** @return if the attached body fixtures will be ignored during raycasting */
  public boolean getIgnoreAttachedBody() {
    return ignoreBody;
  }

  /** Internal method for mesh update depending on ray number */
  void setRayNum(int rays) {
    if (rays < MIN_RAYS) rays = MIN_RAYS;

    rayNum = rays;
    vertexNum = rays + 1;

    segments = new float[vertexNum * 8];
    mx = new float[vertexNum];
    my = new float[vertexNum];
    f = new float[vertexNum];
  }

  /** @return number of rays set for this light */
  public int getRayNum() {
    return rayNum;
  }

  /** Global lights filter * */
  private static Filter globalFilterA = null;
  /** This light specific filter * */
  private Filter filterA = null;

  final RayCastCallback ray =
      new RayCastCallback() {
        @Override
        public final float reportRayFixture(
            Fixture fixture, Vector2 point, Vector2 normal, float fraction) {

          if (!globalContactFilter(fixture)
              || !contactFilter(fixture)
              || (ignoreBody && fixture.getBody() == getBody())) return -1;

          // if (fixture.isSensor())
          // return -1;

          mx[m_index] = point.x;
          my[m_index] = point.y;
          f[m_index] = fraction;
          return fraction;
        }
      };

  private static Filter newContactFilter(short categoryBits, short groupIndex, short maskBits) {
    Filter filter = new Filter();
    filter.categoryBits = categoryBits;
    filter.groupIndex = groupIndex;
    filter.maskBits = maskBits;
    return filter;
  }

  private static boolean contactFilter(Fixture fixture, Filter filterA) {
    if (filterA == null) return true;
    Filter filterB = fixture.getFilterData();
    if (filterA.groupIndex != 0 && filterA.groupIndex == filterB.groupIndex)
      return filterA.groupIndex > 0;

    return (filterA.maskBits & filterB.categoryBits) != 0
        && (filterA.categoryBits & filterB.maskBits) != 0;
  }

  boolean contactFilter(Fixture fixtureB) {
    return contactFilter(fixtureB, filterA);
  }

  /** Sets given contact filter for this light */
  public void setContactFilter(Filter filter) {
    filterA = filter;
  }

  /**
   * Creates new contact filter for this light with given parameters
   *
   * @param categoryBits - see {@link Filter#categoryBits}
   * @param groupIndex - see {@link Filter#groupIndex}
   * @param maskBits - see {@link Filter#maskBits}
   */
  public void setContactFilter(short categoryBits, short groupIndex, short maskBits) {
    filterA = newContactFilter(categoryBits, groupIndex, maskBits);
  }

  boolean globalContactFilter(Fixture fixtureB) {
    return contactFilter(fixtureB, globalFilterA);
  }

  /** Sets given contact filter for ALL LIGHTS */
  public static void setGlobalContactFilter(Filter filter) {
    globalFilterA = filter;
  }

  /**
   * Creates new contact filter for ALL LIGHTS with give parameters
   *
   * @param categoryBits - see {@link Filter#categoryBits}
   * @param groupIndex - see {@link Filter#groupIndex}
   * @param maskBits - see {@link Filter#maskBits}
   */
  public static void setGlobalContactFilter(short categoryBits, short groupIndex, short maskBits) {
    globalFilterA = newContactFilter(categoryBits, groupIndex, maskBits);
  }
}
 /**
  * Sets light color
  *
  * <p>NOTE: you can also use colorless light with shadows, e.g. (0,0,0,1)
  *
  * @param r lights color red component
  * @param g lights color green component
  * @param b lights color blue component
  * @param a lights shadow intensity
  * @see #setColor(Color)
  */
 public void setColor(float r, float g, float b, float a) {
   color.set(r, g, b, a);
   colorF = color.toFloatBits();
   if (staticLight) dirty = true;
 }