package com.junerking.skeleton;
import java.util.ArrayList;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.junerking.skeleton.DataDef.BoneData;
import com.junerking.skeleton.DataDef.DisplayData;
import com.junerking.skeleton.DataDef.NodeData;
import com.junerking.skeleton.DataDef.SubTextureData;
public class Bone {
public String name;
protected NodeData global, node;
public BoneData origin;
private Bone _parent = null;
protected Tween _tween;
protected IMatrix _global_transform_matrix = new IMatrix();
protected IMatrix _transform_matrix_for_child = new IMatrix();
private ArrayList<Bone> _child = new ArrayList<Bone>();
public ArrayList<DisplayData> display_list;
private boolean visible = true;
private SubTextureData current_subtexture_data = null;//用于描述绘图的锚点
private AtlasRegion current_region = null;
protected Armature _armature;
protected Color color = new Color(1.0f, 1.0f, 1.0f, 1.0f);
public Bone() {
_tween = new Tween(this);
origin = new BoneData();
global = new NodeData();
node = new NodeData();
node.scale_x = 0;
node.scale_y = 0;
}
public void setColor(float r, float g, float b, float a) {
this.color.set(r, g, b, a);
}
public void changeDisplay(int index) {
if (index == -2)
index = 0;
if (index < 0) {
visible = false;
} else {
visible = true;
}
DisplayData display_data = display_list.get(index);
if (_armature != null) {
current_subtexture_data = _armature.getSubTextureData(display_data.name);
current_region = _armature.getTextureAtlas().findRegion(display_data.name);
//fix bug: in cocostudio, for the frame animation, the texture_data.with and height is zero
if (current_region != null && current_subtexture_data != null) {
current_subtexture_data.width = current_region.originalWidth;
current_subtexture_data.height = current_region.originalHeight;
}
} else {
current_subtexture_data = null;
current_region = null;
}
transform = true;
}
public void updateZOrder(int z_order) {
z_order += origin.z_order;
if (z_order == global.z_order) {
return;
}
global.z_order = z_order;
if (_armature != null) {
_armature.updateZOrder();
}
}
public boolean isMatrixTransformChanged() {
return transform;
}
public void addChild(Bone child) {
child.removeFromParent();
_child.add(child);
child.setParent(this);
}
public void removeChild(Bone child) {
_child.remove(child);
child.setParent(null);
}
public void removeFromParent() {
if (_parent != null) {
_parent.removeChild(this);
}
}
public void setParent(Bone parent) {
this._parent = parent;
}
public void update(float delta) {
_tween.update(delta);
global.x = origin.x + node.x + _tween.node.x;
global.y = origin.y + node.y + _tween.node.y;
global.skew_x = origin.skew_x + node.skew_x + _tween.node.skew_x;
global.skew_y = origin.skew_y + node.skew_y + _tween.node.skew_y;
global.scale_x = node.scale_x + _tween.node.scale_x;
global.scale_y = node.scale_y + _tween.node.scale_y;
float cos_x = (float) Math.cos(global.skew_x);
float sin_x = (float) Math.sin(global.skew_x);
float cos_y = (float) Math.cos(global.skew_y);
float sin_y = (float) Math.sin(global.skew_y);
_global_transform_matrix.a = global.scale_x * cos_y;
_global_transform_matrix.b = global.scale_x * sin_y;
_global_transform_matrix.c = global.scale_y * sin_x;
_global_transform_matrix.d = global.scale_y * cos_x;
_global_transform_matrix.tx = global.x;
_global_transform_matrix.ty = global.y;
if (_parent != null) {
_global_transform_matrix.mul(_parent._transform_matrix_for_child);
}
if (_child.size() > 0) {
_transform_matrix_for_child.a = cos_y;
_transform_matrix_for_child.b = sin_y;
_transform_matrix_for_child.c = sin_x;
_transform_matrix_for_child.d = cos_x;
_transform_matrix_for_child.tx = global.x;
_transform_matrix_for_child.ty = global.y;
if (_parent != null) {
_transform_matrix_for_child.mul(_parent._transform_matrix_for_child);
}
}
for (int i = 0, n = _child.size(); i < n; i++) {
_child.get(i).update(delta);
}
}
protected boolean transform = true;
protected float[] _v = new float[8];
public void render(SpriteBatch sprite_batch, float parent_alpha) {
if (!visible || current_region == null || current_subtexture_data == null || color.a * parent_alpha == 0)
return;
if (transform) {
float xx = -current_subtexture_data.pivot_x * current_subtexture_data.width;
float yy = -current_subtexture_data.pivot_y * current_subtexture_data.height;
float xw = xx + current_subtexture_data.width;
float yh = yy + current_subtexture_data.height;
if (current_region.packedWidth != current_region.originalWidth || current_region.packedHeight != current_region.originalHeight) {
xw -= current_region.originalWidth - current_region.packedWidth - current_region.offsetX;
yh -= current_region.originalHeight - current_region.packedHeight - current_region.offsetY;
xx += current_region.offsetX;
yy += current_region.offsetY;
}
_v[0] = _global_transform_matrix.a * xx + _global_transform_matrix.c * yy + _global_transform_matrix.tx;
_v[1] = _global_transform_matrix.b * xx + _global_transform_matrix.d * yy + _global_transform_matrix.ty;
_v[2] = _global_transform_matrix.a * xw + _global_transform_matrix.c * yy + _global_transform_matrix.tx;
_v[3] = _global_transform_matrix.b * xw + _global_transform_matrix.d * yy + _global_transform_matrix.ty;
_v[4] = _global_transform_matrix.a * xw + _global_transform_matrix.c * yh + _global_transform_matrix.tx;
_v[5] = _global_transform_matrix.b * xw + _global_transform_matrix.d * yh + _global_transform_matrix.ty;
_v[6] = _global_transform_matrix.a * xx + _global_transform_matrix.c * yh + _global_transform_matrix.tx;
_v[7] = _global_transform_matrix.b * xx + _global_transform_matrix.d * yh + _global_transform_matrix.ty;
}
float aa = color.a * parent_alpha;
sprite_batch.setColor(color.r * aa, color.g * aa, color.b * aa, aa);
sprite_batch.draw(current_region, _v[0], _v[1], _v[2], _v[3], _v[4], _v[5], _v[6], _v[7], current_region.getU(),
current_region.getV2(), current_region.getU2(), current_region.getV());
}
}