package stu.tnt.gdx.graphics.graphics2d;
import static com.badlogic.gdx.graphics.g2d.Batch.C1;
import static com.badlogic.gdx.graphics.g2d.Batch.C2;
import static com.badlogic.gdx.graphics.g2d.Batch.C3;
import static com.badlogic.gdx.graphics.g2d.Batch.C4;
import static com.badlogic.gdx.graphics.g2d.Batch.U1;
import static com.badlogic.gdx.graphics.g2d.Batch.U2;
import static com.badlogic.gdx.graphics.g2d.Batch.U3;
import static com.badlogic.gdx.graphics.g2d.Batch.U4;
import static com.badlogic.gdx.graphics.g2d.Batch.V1;
import static com.badlogic.gdx.graphics.g2d.Batch.V2;
import static com.badlogic.gdx.graphics.g2d.Batch.V3;
import static com.badlogic.gdx.graphics.g2d.Batch.V4;
import static com.badlogic.gdx.graphics.g2d.Batch.X1;
import static com.badlogic.gdx.graphics.g2d.Batch.X2;
import static com.badlogic.gdx.graphics.g2d.Batch.X3;
import static com.badlogic.gdx.graphics.g2d.Batch.X4;
import static com.badlogic.gdx.graphics.g2d.Batch.Y1;
import static com.badlogic.gdx.graphics.g2d.Batch.Y2;
import static com.badlogic.gdx.graphics.g2d.Batch.Y3;
import static com.badlogic.gdx.graphics.g2d.Batch.Y4;
import stu.tnt.gdx.utils.E;
import stu.tnt.gdx.utils.Updater;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Circle;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.NumberUtils;
/**
*
* NSprite.java
*
* Created on: Oct 7, 2012 Author: Trung
*/
public class NSprite extends NativeSpriteBackend {
private final float vertices[] = new float[E.sprite.VERTICES_SIZE];
private Array<Updater> mUpdater = new Array<Updater>(0);
private final Color color = new Color();
// ========================================
// texture region params
Texture texture;
float u, v;
float u2, v2;
int regionWidth, regionHeight;
/************************************************************
* Constructor
************************************************************/
protected NSprite(long address, NWorld world) {
super(address, world);
setColor(1, 1, 1, 1);
}
/************************************************************
* Texture manager method
************************************************************/
public Texture getTexture() {
return texture;
}
public void setTexture(Texture texture) {
this.texture = texture;
final int width = texture.getWidth();
final int height = texture.getHeight();
setRegion(0, 0, width, height);
setSize(width, height);
setOrigin(width >> 1, height >> 1);
setOriginSize(address, width, height);
}
// ===========================================
// region method
/**
* @param width
* The width of the texture region. May be negative to flip the
* sprite when drawn.
* @param height
* The height of the texture region. May be negative to flip the
* sprite when drawn.
*/
public void setRegion(int x, int y, int width, int height) {
float invTexWidth = 1f / texture.getWidth();
float invTexHeight = 1f / texture.getHeight();
setRegion(x * invTexWidth, y * invTexHeight, (x + width) * invTexWidth,
(y + height) * invTexHeight);
regionWidth = Math.abs(width);
regionHeight = Math.abs(height);
setOriginSize(address, regionWidth, regionHeight);
}
/**
* Sets the texture to that of the specified region and sets the coordinates
* relative to the specified region.
*/
public void setRegion(TextureRegion region, int x, int y, int width,
int height) {
texture = region.getTexture();
setRegion(region.getRegionX() + x, region.getRegionY() + y, width,
height);
setOriginSize(address, width, height);
}
public void setRegion(float u, float v, float u2, float v2) {
this.u = u;
this.v = v;
this.u2 = u2;
this.v2 = v2;
regionWidth = Math.round(Math.abs(u2 - u) * texture.getWidth());
regionHeight = Math.round(Math.abs(v2 - v) * texture.getHeight());
setOriginSize(address, regionWidth, regionHeight);
float[] vertices = this.vertices;
vertices[U1] = u;
vertices[V1] = v2;
vertices[U2] = u;
vertices[V2] = v;
vertices[U3] = u2;
vertices[V3] = v;
vertices[U4] = u2;
vertices[V4] = v2;
}
/** Sets the texture and coordinates to the specified region. */
public void setRegion(TextureRegion region) {
texture = region.getTexture();
setRegion(region.getU(), region.getV(), region.getU2(), region.getV2());
setOriginSize(address, regionWidth, regionHeight);
}
public void setU(float u) {
this.u = u;
regionWidth = Math.round(Math.abs(u2 - u) * texture.getWidth());
setOriginSize(address, regionWidth, regionHeight);
vertices[U1] = u;
vertices[U2] = u;
}
public void setV(float v) {
this.v = v;
regionHeight = Math.round(Math.abs(v2 - v) * texture.getHeight());
setOriginSize(address, regionWidth, regionHeight);
vertices[V2] = v;
vertices[V3] = v;
}
public void setU2(float u2) {
this.u2 = u2;
regionWidth = Math.round(Math.abs(u2 - u) * texture.getWidth());
setOriginSize(address, regionWidth, regionHeight);
vertices[U3] = u2;
vertices[U4] = u2;
}
public void setV2(float v2) {
this.v2 = v2;
regionHeight = Math.round(Math.abs(v2 - v) * texture.getHeight());
setOriginSize(address, regionWidth, regionHeight);
vertices[V1] = v2;
vertices[V4] = v2;
}
// ============================================
// getter
public boolean isFlipX() {
return u > u2;
}
public boolean isFlipY() {
return v > v2;
}
public float getU() {
return u;
}
public float getV() {
return v;
}
public float getU2() {
return u2;
}
public float getV2() {
return v2;
}
public int getRegionX() {
return Math.round(u * texture.getWidth());
}
public int getRegionY() {
return Math.round(v * texture.getHeight());
}
/** Returns the region's width. */
public int getRegionWidth() {
return regionWidth;
}
/** Returns the region's height. */
public int getRegionHeight() {
return regionHeight;
}
/************************************************************
* Java sprite method
************************************************************/
// ==============================================
// setter
@Override
public void setBounds(float x, float y, float width, float height) {
setBounds(address, x, y, width, height);
if (isDirty(address))
return;
float x2 = x + width;
float y2 = y + height;
final float[] vertices = this.vertices;
vertices[X1] = x;
vertices[Y1] = y;
vertices[X2] = x;
vertices[Y2] = y2;
vertices[X3] = x2;
vertices[Y3] = y2;
vertices[X4] = x2;
vertices[Y4] = y;
}
@Override
public void setSize(float width, float height) {
setSize(address, width, height);
if (isDirty(address))
return;
float x = getX();
float y = getY();
float x2 = x + width;
float y2 = y + height;
final float[] vertices = this.vertices;
vertices[X1] = x;
vertices[Y1] = y;
vertices[X2] = x;
vertices[Y2] = y2;
vertices[X3] = x2;
vertices[Y3] = y2;
vertices[X4] = x2;
vertices[Y4] = y;
}
@Override
public void setPosition(float x, float y) {
translate(x - getX(), y - getY());
}
@Override
public void setX(float x) {
translateX(x - getX());
}
@Override
public void setY(float y) {
translateY(y - getY());
}
@Override
public void translate(float xAmount, float yAmount) {
translate(address, xAmount, yAmount);
if (isDirty(address))
return;
final float[] vertices = this.vertices;
vertices[X1] += xAmount;
vertices[Y1] += yAmount;
vertices[X2] += xAmount;
vertices[Y2] += yAmount;
vertices[X3] += xAmount;
vertices[Y3] += yAmount;
vertices[X4] += xAmount;
vertices[Y4] += yAmount;
}
@Override
public void translateX(float xAmount) {
translateX(address, xAmount);
if (isDirty(address))
return;
final float[] vertices = this.vertices;
vertices[X1] += xAmount;
vertices[X2] += xAmount;
vertices[X3] += xAmount;
vertices[X4] += xAmount;
}
@Override
public void translateY(float yAmount) {
translateY(address, yAmount);
if (isDirty(address))
return;
final float[] vertices = this.vertices;
vertices[Y1] += yAmount;
vertices[Y2] += yAmount;
vertices[Y3] += yAmount;
vertices[Y4] += yAmount;
}
@Override
public void setOrigin(float originX, float originY) {
setOrigin(address, originX, originY);
}
@Override
public void setRotation(float degree) {
setRotation(address, degree);
}
@Override
public void rotate(float degree) {
rotate(address, degree);
}
@Override
public void setScale(float scaleXY) {
setScale(address, scaleXY);
}
@Override
public void setScale(float scaleX, float scaleY) {
setScale(address, scaleX, scaleY);
}
@Override
public void scale(float amount) {
scale(address, amount);
}
@Override
public void setColor(float r, float g, float b, float a) {
int intBits = ((int) (255 * a) << 24) | ((int) (255 * b) << 16)
| ((int) (255 * g) << 8) | ((int) (255 * r));
float color = NumberUtils.intToFloatColor(intBits);
final float[] vertices = this.vertices;
vertices[C1] = color;
vertices[C2] = color;
vertices[C3] = color;
vertices[C4] = color;
}
@Override
public void setColor(Color tint) {
float color = tint.toFloatBits();
final float[] vertices = this.vertices;
vertices[C1] = color;
vertices[C2] = color;
vertices[C3] = color;
vertices[C4] = color;
}
// =======================================================
// getter
@Override
public float[] getVertices() {
return vertices;
}
@Override
public float getX() {
return getX(address);
}
@Override
public float getCenterX() {
return getCenterX(address);
}
@Override
public float getY() {
return getY(address);
}
@Override
public float getCenterY() {
return getCenterY(address);
}
@Override
public float getWidth() {
return getWidth(address);
}
@Override
public float getHeight() {
return getHeight(address);
}
@Override
public float getOriginX() {
return getOriginX(address);
}
@Override
public float getOriginY() {
return getOriginY(address);
}
@Override
public float getRotation() {
return getRotation(address);
}
@Override
public float getScaleX() {
return getScaleX(address);
}
@Override
public float getScaleY() {
return getScaleY(address);
}
@Deprecated
public Rectangle getBoundingRectangle() {
return null;
}
@Deprecated
public float[] getBoundingFloatRect(float offset) {
return null;
}
@Deprecated
public Circle getBoundingCircle() {
return null;
}
/**
* Returns the color of this sprite. Changing the returned color will have
* no affect, {@link #setColor(Color)} or
* {@link #setColor(float, float, float, float)} must be used.
*/
public Color getColor() {
int intBits = NumberUtils.floatToIntColor(vertices[C1]);
Color color = this.color;
color.r = (intBits & 0xff) / 255f;
color.g = ((intBits >>> 8) & 0xff) / 255f;
color.b = ((intBits >>> 16) & 0xff) / 255f;
color.a = ((intBits >>> 24) & 0xff) / 255f;
return color;
}
// ===============================================
// processor
@Override
public void postUpdater(Updater updater) {
if (mUpdater.contains(updater, true))
return;
updater.start();
this.mUpdater.add(updater);
}
public int sizeUpdater() {
return mUpdater.size;
}
@Override
public void removeUpdater(Updater updater) {
mUpdater.removeValue(updater, true);
}
@Override
public void noUpdater() {
this.mUpdater.clear();
}
@Override
public void update(float delta) {
getVertices(address, vertices);
if (isPooled)
return;
// ============= update updatable =============
for (int i = 0, n = mUpdater.size; i < n; i++) {
final Updater tmp = mUpdater.get(i);
if (!tmp.isStoped())
tmp.update(this, delta);
else {
mUpdater.removeIndex(i);
i--;
n--;
}
}
}
@Override
public void draw(Batch batch) {
if (texture != null)
batch.draw(texture, vertices, 0, E.sprite.VERTICES_SIZE);
}
@Override
public void draw(Batch batch, float alpha) {
Color color = getColor();
float oldAlpha = color.a;
color.a *= alpha;
setColor(color);
draw(batch);
color.a = oldAlpha;
setColor(color);
}
@Override
public void reset() {
super.reset();
vertices[X1] = 0;
vertices[X2] = 0;
vertices[X3] = 0;
vertices[X4] = 0;
vertices[Y1] = 0;
vertices[Y2] = 0;
vertices[Y3] = 0;
vertices[Y4] = 0;
setColor(1, 1, 1, 1);
noUpdater();
}
}