Ejemplo n.º 1
0
  /**
   * @param group an empty group to be the parent
   * @return the group with the current selection
   */
  public Group createGroup(Group group) {
    // New group has the same transformation as this
    group.setBounds(getX(), getY(), getWidth(), getHeight());
    group.setOrigin(getOriginX(), getOriginY());
    group.setRotation(getRotation());
    group.setScale(getScaleX(), getScaleY());

    // Each children in the group must be contained by the new group
    Array<Actor> children = getChildren();
    children.sort(
        new Comparator<Actor>() {
          @Override
          public int compare(Actor actor, Actor actor2) {
            return ((SelectionGhost) actor).getRepresentedActor().getZIndex()
                - ((SelectionGhost) actor2).getRepresentedActor().getZIndex();
          }
        });

    for (Actor actor : children) {
      SelectionGhost ghost = (SelectionGhost) actor;
      Actor representedActor = ghost.getRepresentedActor();
      representedActor.setPosition(ghost.getX(), ghost.getY());
      representedActor.setRotation(ghost.getRotation());
      representedActor.setScale(ghost.getScaleX(), ghost.getScaleY());
      group.addActor(representedActor);
    }
    return group;
  }
Ejemplo n.º 2
0
  /** Sets position, rotation, scale and origin in actor to meet the 3 given points */
  public static void applyTransformation(
      Actor actor, Vector2 origin, Vector2 tangent, Vector2 normal) {
    /*
     * We are going to calculate the affine transformation for the actor to
     * fit the bounds represented by the handles. The affine transformation
     * is defined as follows:
     */
    // |a b tx|
    // |c d ty|=|Translation Matrix| x |Scale Matrix| x |Rotation
    // Matrix|
    // |0 0 1 |
    /*
     * More info about affine transformations:
     * https://people.gnome.org/~mathieu
     * /libart/libart-affine-transformation-matrices.html, To obtain the
     * matrix, we want to resolve the following equation system:
     */
    // | a b tx| |0| |o.x|
    // | c d ty|*|0|=|o.y|
    // | 0 0 1 | |1| | 1 |
    //
    // | a b tx| |w| |t.x|
    // | c d ty|*|0|=|t.y|
    // | 0 0 1 | |1| | 1 |
    //
    // | a b tx| |0| |n.x|
    // | c d ty|*|h|=|n.y|
    // | 0 0 1 | |1| | 1 |
    /*
     * where o is handles[0] (origin), t is handles[2] (tangent) and n is
     * handles[6] (normal), w is actor.getWidth() and h is
     * actor.getHeight().
     *
     * This matrix defines that the 3 points defining actor bounds are
     * transformed to the 3 points defining modifier bounds. E.g., we want
     * that actor origin (0,0) is transformed to (handles[0].x,
     * handles[0].y), and that is expressed in the first equation.
     *
     * Resolving these equations is obtained:
     */
    // a = (t.x - o.y) / w
    // b = (t.y - o.y) / w
    // c = (n.x - o.x) / h
    // d = (n.y - o.y) / h
    /*
     * Values for translation, scale and rotation contained by the matrix
     * can be obtained directly making operations over a, b, c and d:
     */
    // tx = o.x
    // ty = o.y
    // sx = sqrt(a^2+b^2)
    // sy = sqrt(c^2+d^2)
    // rotation = atan(c/d)
    // or
    // rotation = atan(-b/a)
    /*
     * Rotation can give two different values (this happens when there is
     * more than one way of obtaining the same transformation). To avoid
     * that, we ignore the rotation to obtain the final values.
     */

    Vector2 tmp1 = Pools.obtain(Vector2.class);
    Vector2 tmp2 = Pools.obtain(Vector2.class);
    Vector2 tmp3 = Pools.obtain(Vector2.class);
    Vector2 tmp4 = Pools.obtain(Vector2.class);
    Vector2 tmp5 = Pools.obtain(Vector2.class);

    Vector2 o = tmp1.set(origin.x, origin.y);
    Vector2 t = tmp2.set(tangent.x, tangent.y);
    Vector2 n = tmp3.set(normal.x, normal.y);

    Vector2 vt = tmp4.set(t).sub(o);
    Vector2 vn = tmp5.set(n).sub(o);

    // Ignore rotation
    float rotation = actor.getRotation();
    vt.rotate(-rotation);
    vn.rotate(-rotation);

    t.set(vt).add(o);
    n.set(vn).add(o);

    Vector2 bottomLeft = Pools.obtain(Vector2.class);
    Vector2 size = Pools.obtain(Vector2.class);

    calculateBounds(actor, bottomLeft, size);

    float a = (t.x - o.x) / size.x;
    float c = (t.y - o.y) / size.x;
    float b = (n.x - o.x) / size.y;
    float d = (n.y - o.y) / size.y;

    Pools.free(tmp1);
    Pools.free(tmp2);
    Pools.free(tmp3);
    Pools.free(tmp4);
    Pools.free(tmp5);
    Pools.free(bottomLeft);
    Pools.free(size);

    // Math.sqrt gives a positive value, but it also have a negatives.
    // The
    // signum is calculated computing the current rotation
    float signumX = vt.angle() > 90.0f && vt.angle() < 270.0f ? -1.0f : 1.0f;
    float signumY = vn.angle() > 180.0f ? -1.0f : 1.0f;

    float scaleX = (float) Math.sqrt(a * a + b * b) * signumX;
    float scaleY = (float) Math.sqrt(c * c + d * d) * signumY;

    actor.setScale(scaleX, scaleY);

    /*
     * To obtain the correct translation value we need to subtract the
     * amount of translation due to the origin.
     */
    tmpMatrix.setToTranslation(actor.getOriginX(), actor.getOriginY());
    tmpMatrix.rotate(actor.getRotation());
    tmpMatrix.scale(actor.getScaleX(), actor.getScaleY());
    tmpMatrix.translate(-actor.getOriginX(), -actor.getOriginY());

    /*
     * Now, the matrix has how much translation is due to the origin
     * involved in the rotation and scaling operations
     */
    float x = o.x - tmpMatrix.getValues()[Matrix3.M02];
    float y = o.y - tmpMatrix.getValues()[Matrix3.M12];
    actor.setPosition(x, y);
  }
Ejemplo n.º 3
0
  @Override
  public void render() {
    Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    if (Gdx.input.isTouched()) {
      stage.screenToStageCoordinates(stageCoords.set(Gdx.input.getX(), Gdx.input.getY()));
      Actor actor = stage.hit(stageCoords.x, stageCoords.y, true);
      if (actor != null)
        actor.setColor(
            (float) Math.random(),
            (float) Math.random(),
            (float) Math.random(),
            0.5f + 0.5f * (float) Math.random());
    }

    Array<Actor> actors = stage.getActors();
    int len = actors.size;
    if (rotateSprites) {
      for (int i = 0; i < len; i++) actors.get(i).rotateBy(Gdx.graphics.getDeltaTime() * 10);
    }

    scale += vScale * Gdx.graphics.getDeltaTime();
    if (scale > 1) {
      scale = 1;
      vScale = -vScale;
    }
    if (scale < 0.5f) {
      scale = 0.5f;
      vScale = -vScale;
    }

    len = sprites.size;
    for (int i = 0; i < len; i++) {
      Actor sprite = sprites.get(i);
      if (rotateSprites) sprite.rotateBy(-40 * Gdx.graphics.getDeltaTime());
      else sprite.setRotation(0);

      if (scaleSprites) {
        sprite.setScale(scale);
      } else {
        sprite.setScale(1);
      }
    }

    stage.draw();

    renderer.begin(ShapeType.Point);
    renderer.setColor(1, 0, 0, 1);
    len = actors.size;
    for (int i = 0; i < len; i++) {
      Group group = (Group) actors.get(i);
      renderer.point(group.getX() + group.getOriginX(), group.getY() + group.getOriginY(), 0);
    }
    renderer.end();

    fps.setText(
        "fps: "
            + Gdx.graphics.getFramesPerSecond()
            + ", actors "
            + sprites.size
            + ", groups "
            + sprites.size);
    ui.draw();
  }