Skip to content

Commit

Permalink
Merge pull request #97 from Sasun/compositeItemManualResize
Browse files Browse the repository at this point in the history
adds composite item manual resize support. Bugfix
  • Loading branch information
azakhary committed May 3, 2016
2 parents 1aba2aa + 2a4b496 commit 0fff05a
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,55 @@
import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.Family;
import com.badlogic.ashley.systems.IteratingSystem;
import com.uwsoft.editor.renderer.components.ParentNodeComponent;
import com.uwsoft.editor.renderer.components.SpineDataComponent;
import com.uwsoft.editor.renderer.components.TransformComponent;

public class SpineSystem extends IteratingSystem {

private ComponentMapper<SpineObjectComponent> spineObjectComponentMapper = ComponentMapper.getFor(SpineObjectComponent.class);
private ComponentMapper<TransformComponent> transformComponentMapper = ComponentMapper.getFor(TransformComponent.class);

public SpineSystem() {
super(Family.all(SpineDataComponent.class).get());
}

@Override
protected void processEntity(Entity entity, float deltaTime) {

TransformComponent transformComponent = transformComponentMapper.get(entity);
SpineObjectComponent spineObjectComponent = spineObjectComponentMapper.get(entity);

spineObjectComponent.skeleton.updateWorldTransform(); //
spineObjectComponent.state.update(deltaTime); // Update the animation time.
spineObjectComponent.state.apply(spineObjectComponent.skeleton); // Poses skeleton using current animations. This sets the bones' local SRT.
spineObjectComponent.skeleton.setPosition(transformComponent.x - spineObjectComponent.minX, transformComponent.y - spineObjectComponent.minY);
}
private ComponentMapper<SpineObjectComponent> spineObjectComponentMapper = ComponentMapper.getFor(SpineObjectComponent.class);
private ComponentMapper<TransformComponent> transformComponentMapper = ComponentMapper.getFor(TransformComponent.class);

public SpineSystem() {
super(Family.all(SpineDataComponent.class).get());
}

@Override
protected void processEntity(Entity entity, float deltaTime) {

TransformComponent transformComponent = transformComponentMapper.get(entity);
SpineObjectComponent spineObjectComponent = spineObjectComponentMapper.get(entity);

ParentNodeComponent parentNodeComponent = entity.getComponent(ParentNodeComponent.class);
Entity parentEntity = parentNodeComponent.parentEntity;
TransformComponent parentTransformComponent = transformComponentMapper.get(parentEntity);
float offsetX = 0;
float offsetY = 0;

if (parentTransformComponent.scaleX == 1 && parentTransformComponent.scaleY == 1 && parentTransformComponent.rotation == 0) {
offsetX = parentTransformComponent.x;
offsetY = parentTransformComponent.y;

while (true) {
parentNodeComponent = parentEntity.getComponent(ParentNodeComponent.class);
if (parentNodeComponent == null) {
break;
}

parentEntity = parentNodeComponent.parentEntity;
if (parentEntity == null) {
break;
}

parentTransformComponent = transformComponentMapper.get(parentEntity);
offsetX += parentTransformComponent.x;
offsetY += parentTransformComponent.y;
}
}

spineObjectComponent.skeleton.updateWorldTransform(); //
spineObjectComponent.state.update(deltaTime); // Update the animation time.
spineObjectComponent.state.apply(spineObjectComponent.skeleton); // Poses skeleton using current animations. This sets the bones' local SRT.
spineObjectComponent.skeleton.setPosition(transformComponent.x - spineObjectComponent.minX + offsetX, transformComponent.y - spineObjectComponent.minY + offsetY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.badlogic.gdx.math.Matrix4;

public class CompositeTransformComponent implements Component {
public boolean automaticResize = false;
public boolean transform = false;
public final Affine2 worldTransform = new Affine2();
public final Matrix4 computedTransform = new Matrix4();
Expand Down
4 changes: 4 additions & 0 deletions src/com/uwsoft/editor/renderer/data/CompositeItemVO.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.uwsoft.editor.renderer.data;

import com.badlogic.ashley.core.Entity;
import com.uwsoft.editor.renderer.components.CompositeTransformComponent;
import com.uwsoft.editor.renderer.components.DimensionsComponent;
import com.uwsoft.editor.renderer.components.MainItemComponent;
import com.uwsoft.editor.renderer.utils.ComponentRetriever;
Expand All @@ -18,6 +19,7 @@ public class CompositeItemVO extends MainItemVO {

public float width;
public float height;
public boolean automaticResize;

public CompositeItemVO() {
composite = new CompositeVO();
Expand Down Expand Up @@ -67,9 +69,11 @@ public void loadFromEntity(Entity entity) {
composite.loadFromEntity(entity);

DimensionsComponent dimensionsComponent = ComponentRetriever.get(entity, DimensionsComponent.class);
CompositeTransformComponent compositeTransformComponent = ComponentRetriever.get(entity, CompositeTransformComponent.class);

width = dimensionsComponent.width;
height = dimensionsComponent.height;
automaticResize = compositeTransformComponent.automaticResize;
}

public void cleanIds() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ protected void createNodeComponent(Entity root, Entity entity) {
protected void createCompositeComponents(Entity entity, CompositeItemVO vo) {
CompositeTransformComponent compositeTransform = new CompositeTransformComponent();

compositeTransform.automaticResize = vo.automaticResize;

LayerMapComponent layerMap = new LayerMapComponent();
if(vo.composite.layers.size() == 0) {
vo.composite.layers.add(LayerItemVO.createDefault());
Expand Down
215 changes: 116 additions & 99 deletions src/com/uwsoft/editor/renderer/systems/CompositeSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,119 +5,136 @@
import com.badlogic.ashley.core.Family;
import com.badlogic.ashley.systems.IteratingSystem;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Matrix3;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.SnapshotArray;
import com.uwsoft.editor.renderer.components.CompositeTransformComponent;
import com.uwsoft.editor.renderer.components.DimensionsComponent;
import com.uwsoft.editor.renderer.components.NodeComponent;
import com.uwsoft.editor.renderer.components.TransformComponent;
import com.uwsoft.editor.renderer.components.*;
import com.uwsoft.editor.renderer.utils.TransformMathUtils;

public class CompositeSystem extends IteratingSystem {

private ComponentMapper<DimensionsComponent> dimensionsMapper;
private ComponentMapper<TransformComponent> transformMapper;
private ComponentMapper<NodeComponent> nodeMapper;

private DimensionsComponent dimensionsComponent;
private TransformComponent transformComponent;
private NodeComponent nodeComponent;

public CompositeSystem() {
super(Family.all(CompositeTransformComponent.class).get());
dimensionsMapper = ComponentMapper.getFor(DimensionsComponent.class);
transformMapper = ComponentMapper.getFor(TransformComponent.class);
nodeMapper = ComponentMapper.getFor(NodeComponent.class);
}

@Override
protected void processEntity(Entity entity, float deltaTime) {
dimensionsComponent = dimensionsMapper.get(entity);
nodeComponent = nodeMapper.get(entity);
private ComponentMapper<DimensionsComponent> dimensionsMapper;
private ComponentMapper<TransformComponent> transformMapper;
private ComponentMapper<NodeComponent> nodeMapper;
private ComponentMapper<CompositeTransformComponent> compositeMapper;

private DimensionsComponent dimensionsComponent;
private NodeComponent nodeComponent;

private final Vector2 p1 = new Vector2();
private final Vector2 p2 = new Vector2();
private final Vector2 p3 = new Vector2();
private final Vector2 p4 = new Vector2();
private final Vector2 tmpBoundPoints = new Vector2();

public CompositeSystem() {
super(Family.all(CompositeTransformComponent.class).get());
dimensionsMapper = ComponentMapper.getFor(DimensionsComponent.class);
transformMapper = ComponentMapper.getFor(TransformComponent.class);
nodeMapper = ComponentMapper.getFor(NodeComponent.class);
compositeMapper = ComponentMapper.getFor(CompositeTransformComponent.class);
}

@Override
public void processEntity(Entity entity, float deltaTime) {
dimensionsComponent = dimensionsMapper.get(entity);
nodeComponent = nodeMapper.get(entity);
// if(dimensionsComponent.boundBox == null){
// dimensionsComponent.boundBox = new Rectangle();
// }
recalculateSize();
}

public void recalculateSize() {
// before: float lowerX = 0, lowerY = 0 <- We check Min(0, Something) at the bottom of the function this way!
float lowerX = Float.MAX_VALUE, lowerY = Float.MAX_VALUE, upperX = Float.MIN_VALUE, upperY = Float.MIN_VALUE;
// recalculateSize();
CompositeTransformComponent compositeTransformComponent = compositeMapper.get(entity);
ViewPortComponent viewPortComponent = entity.getComponent(ViewPortComponent.class);
if (compositeTransformComponent != null && compositeTransformComponent.automaticResize && viewPortComponent == null) {
recalculateSize();
}
}

private void recalculateSize() {
float lowerX = Float.MAX_VALUE;
float lowerY = Float.MAX_VALUE;
float upperX = Float.MIN_VALUE;
float upperY = Float.MIN_VALUE;
SnapshotArray<Entity> entities = nodeComponent.children;

float cos = 0;
float sin = 0;
float x1,y1,x2,y2,x3,y3,x4,y4;
float worldOriginX;
float worldOriginY;
float fx;
float fy;
float fx2;
float fy2;

for (int i = 0; i < entities.size; i++) {
Entity entity = entities.get(i);
transformComponent = transformMapper.get(entity);
DimensionsComponent childDimentionsComponent = dimensionsMapper.get(entity);

worldOriginX = transformComponent.x+transformComponent.originX;
worldOriginY = transformComponent.y+transformComponent.originY;

fx = -transformComponent.originX;
fy = -transformComponent.originY;
fx2 = childDimentionsComponent.width-transformComponent.originX;
fy2 = childDimentionsComponent.height-transformComponent.originY;

if (transformComponent.scaleX != 1 || transformComponent.scaleY != 1) {
fx *= transformComponent.scaleX;
fy *= transformComponent.scaleY;
fx2 *= transformComponent.scaleX;
fy2 *= transformComponent.scaleY;
}

x1 = fx;
y1 = fy;
x2 = fx;
y2 = fy2;
x3 = fx2;
y3 = fy;
x4 = fx2;
y4 = fy2;

if(transformComponent.rotation != 0){
cos = MathUtils.cosDeg(transformComponent.rotation);
sin = MathUtils.sinDeg(transformComponent.rotation);

x1 = fx * cos - fy * sin;
y1 = fx * sin + fy * cos;

x2 = fx * cos - fy2 * sin;
y2 = fx * sin + fy2 * cos;

x3 = fx2 * cos - fy * sin;
y3 = fx2 * sin + fy * cos;

x4 = fx2 * cos - fy2 * sin;
y4 = fx2 * sin + fy2 * cos;
}

x1 += worldOriginX;
y1 += worldOriginY;
x2 += worldOriginX;
y2 += worldOriginY;
x3 += worldOriginX;
y3 += worldOriginY;
x4 += worldOriginX;
y4 += worldOriginY;

lowerX = Math.min(Math.min(Math.min(Math.min(x1, x2),x3),x4),lowerX);
upperX = Math.max(Math.max(Math.max(Math.max(x1, x2),x3),x4),upperX);
lowerY = Math.min(Math.min(Math.min(Math.min(y1, y2),y3),y4),lowerY);
upperY = Math.max(Math.max(Math.max(Math.max(y1, y2),y3),y4),upperY);
for (Entity entity : entities) {
TransformComponent transformComponent = transformMapper.get(entity);
DimensionsComponent childDimCom = dimensionsMapper.get(entity);
float x = transformComponent.x;
float y = transformComponent.y;
float width = childDimCom.width;
float height = childDimCom.height;

Matrix3 transMat = TransformMathUtils.transform(transformComponent);

p1.set(x, y).mul(transMat);
p2.set(x + width, y).mul(transMat);
p3.set(x + width, y + height).mul(transMat);
p4.set(x, y + height).mul(transMat);

tmpBoundPoints.set(lowerX, 0);
lowerX = getX(MinMaxOp.MIN, p1, p2, p3, p4, tmpBoundPoints);

tmpBoundPoints.set(upperX, 0);
upperX = getX(MinMaxOp.MAX, p1, p2, p3, p4, tmpBoundPoints);

tmpBoundPoints.set(0, lowerY);
lowerY = getY(MinMaxOp.MIN, p1, p2, p3, p4, tmpBoundPoints);

tmpBoundPoints.set(0, upperY);
upperY = getY(MinMaxOp.MAX, p1, p2, p3, p4, tmpBoundPoints);
}

for (Entity entity : entities) {
if (lowerX == 0 && lowerY == 0) break;
TransformComponent transformComponent = transformMapper.get(entity);
transformComponent.x -= lowerX;
transformComponent.y -= lowerY;
}

dimensionsComponent.width = (upperX - lowerX);
dimensionsComponent.height = (upperY - lowerY);
lowerX = 0;
lowerY = 0;
dimensionsComponent.boundBox.set(lowerX, lowerY, dimensionsComponent.width, dimensionsComponent.height);
}

private float getX(MinMaxOp op, Vector2... points) {
float pointX = points[0].x;
for (Vector2 point : points) {
pointX = op.compare(pointX, point.x);
}
return pointX;
}

private float getY(MinMaxOp op, Vector2... points) {
float pointY = points[0].y;
for (Vector2 point : points) {
pointY = op.compare(pointY, point.y);
}
return pointY;
}

private enum MinMaxOp {
MIN("<") {
@Override
public float compare(float a, float b) {
return (a < b) ? a : b;
}
},

MAX(">") {
@Override
public float compare(float a, float b) {
return (a > b) ? a : b;
}
};

private String minMaxOperator;

MinMaxOp(String minMaxOperator) {
this.minMaxOperator = minMaxOperator;
}

public abstract float compare(float a, float b);
}
}
Loading

0 comments on commit 0fff05a

Please sign in to comment.