public void updateProperties() { if (editActors == null) return; updateProperties = true; Actor model = editActors.get(0); getStage().setKeyboardFocus(null); name.setText(model.getName()); visible.setChecked(model.isVisible()); positionX.setText(String.format(Locale.ENGLISH, "%.2f", model.getX())); positionY.setText(String.format(Locale.ENGLISH, "%.2f", model.getY())); rotation.setText(String.format(Locale.ENGLISH, "%.2f", model.getRotation())); lockRatio.setChecked(Math.abs(model.getScaleX() - model.getScaleY()) < 0.01f); scaleX.setText(String.format(Locale.ENGLISH, "%.2f", model.getScaleX())); scaleY.setText(String.format(Locale.ENGLISH, "%.2f", model.getScaleY())); Color color = model.getColor(); r.setText(String.format(Locale.ENGLISH, "%.0f", color.r * 255)); g.setText(String.format(Locale.ENGLISH, "%.0f", color.g * 255)); b.setText(String.format(Locale.ENGLISH, "%.0f", color.b * 255)); a.setText(String.format(Locale.ENGLISH, "%.0f", color.a * 255)); scaleY.setDisabled(lockRatio.isChecked()); scaleY.setColor(lockRatio.isChecked() ? disableColor : enableColor); updateProperties = false; }
/** * Transforms the specified point in the actor's coordinates to be in the stage's coordinates. * Note this method will ONLY work for screen aligned, unrotated, unscaled actors! */ public Vector2 localToStageCoordinates(Vector2 localCoords) { Actor actor = this; while (actor != null) { if (actor.getRotation() != 0 || actor.getScaleX() != 1 || actor.getScaleY() != 1) throw new GdxRuntimeException("Only unrotated and unscaled actors may use this method."); localCoords.x += actor.getX(); localCoords.y += actor.getY(); actor = actor.getParent(); } return localCoords; }
public SelectionGhost(ShapeRenderer shapeRenderer, Actor representedActor) { this.shapeRenderer = shapeRenderer; this.representedActor = representedActor; setOrigin(representedActor.getOriginX(), representedActor.getOriginY()); setBounds( representedActor.getX(), representedActor.getY(), representedActor.getWidth(), representedActor.getHeight()); setRotation(representedActor.getRotation()); setScale(representedActor.getScaleX(), representedActor.getScaleY()); startingRotation = representedActor.getRotation(); }
/** * Creates a {@link ModelEntity}. This method should only be invoked if the return value of the * {@link #save()} method was true. */ public void createSceneElement() { ModelEntity savedElement = this.controller.getTemplates().createSceneElement(this.savePath.path()); Actor rootGroup = scaledView.getGroupEditorDragListener().getRootGroup(); Actor scaledAct = rootGroup == null ? scaledView : rootGroup; savedElement.setScaleX(1 / scaledAct.getScaleX()); savedElement.setScaleY(1 / scaledAct.getScaleY()); Vector2 pos = mesh.getPosition(); savedElement.setX(pos.x - scaledAct.getX()); savedElement.setY(pos.y - scaledAct.getY()); Q.getComponent(savedElement, RepoElement.class).setThumbnail(thumbSavePath.name()); this.controller.action(AddSceneElement.class, savedElement); }
/** 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); }