package com.gebauz.bauzoid.graphics.spritex;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.gebauz.bauzoid.graphics.Graphics;
import com.gebauz.bauzoid.graphics.GraphicsObject;
import com.gebauz.bauzoid.graphics.model.Geometry.PrimitiveType;
import com.gebauz.bauzoid.graphics.model.SimpleGeometry;
import com.gebauz.bauzoid.graphics.renderstates.RenderStates;
import com.gebauz.bauzoid.graphics.sprite.SpriteShader;
import com.gebauz.bauzoid.math.Matrix4;
import com.gebauz.bauzoid.math.Vector2;
/** Sprite class.
* Implements a 2D sprite that renders from a portion of a
* texture to a quad onscreen.
*
* The class is capable of
* - Rotation and scale transformation via pivot point
* - Fading (done through shader instead of setting vertex colors)
*
* For using multiple texture regions as frames,
* use @link AtlasSprite.
*/
public class Sprite
extends GraphicsObject
{
public SpriteParameters param =
new SpriteParameters
();
protected Texture mTexture =
null;
protected SimpleGeometry mMesh =
null;
private Matrix4 mScale =
new Matrix4
();
private Matrix4 mMirror =
new Matrix4
();
private Matrix4 mPivotTranslate =
new Matrix4
();
private Matrix4 mRotateZ =
new Matrix4
();
private Matrix4 mTranslate =
new Matrix4
();
private Matrix4 mModelMatrix =
new Matrix4
();
protected String mFilename =
null;
protected boolean mIsAsync =
false;
/** Constructor. Does not load anything yet
*/
public Sprite
(Graphics graphics,
String filename
)
{
super(graphics
);
mFilename = filename
;
}
/** Called during asynchronous loading - initiates texture loading. */
public void initAsync
()
{
if (mFilename ==
null)
return;
mIsAsync =
true;
getAssetManager
().
load(mFilename, Texture.
class);
}
/** Called synchronously after initAsync() has been called. */
public void init
(float _x,
float _y,
float _w,
float _h,
float _pivotX,
float _pivotY
)
{
if (mFilename ==
null)
return;
if (!mIsAsync
)
{
// load texture synchronously
mTexture =
new Texture
(Gdx.
files.
internal(mFilename
));
}
else
{
// grab texture that should be loaded asynchronously already
mTexture = getAssetManager
().
get(mFilename, Texture.
class);
}
param.
x = _x
;
param.
y = _y
;
param.
w = _w
;
param.
h = _h
;
param.
pivotX = _pivotX
;
param.
pivotY = _pivotY
;
initGeometry
();
}
public void init
(float _x,
float _y,
float _w,
float _h
)
{
init
(_x, _y, _w, _h, _w/
2, _h/
2);
}
public void init
()
{
init
(0,
0,
0,
0);
if (mTexture
!=
null)
{
param.
w = mTexture.
getWidth();
param.
h = mTexture.
getHeight();
param.
pivotX = param.
w/
2;
param.
pivotY = param.
h/
2;
}
}
protected void initGeometry
()
{
float[] vertices =
{
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f
};
float[] texCoords =
{
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
};
float[] colors =
{
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
};
short[] indices =
{
0,
1,
2,
0,
2,
3
};
mMesh =
new SimpleGeometry
(getGraphics
(), PrimitiveType.
TRIANGLES);
mMesh.
setPositions(vertices
);
mMesh.
setTexCoords(texCoords,
false);
mMesh.
setColors(colors
);
mMesh.
setIndices(indices
);
}
public void dispose
()
{
if (mTexture
!=
null)
{
if (mIsAsync
)
{
getAssetManager
().
unload(mFilename
);
}
else
{
mTexture.
dispose();
}
mTexture =
null;
}
}
public void update
(float deltaTime
)
{
}
public void render
()
{
render
(param.
x, param.
y, param.
w, param.
h);
}
public void render
(float _x,
float _y,
float _w,
float _h
)
{
render
(_x, _y, _w, _h, param.
pivotX, param.
pivotY, param.
angle, param.
mirrorX, param.
mirrorY);
}
public void render
(float _x,
float _y,
float _w,
float _h,
float _pivotX,
float _pivotY
)
{
render
(_x, _y, _w, _h, _pivotX, _pivotY, param.
angle, param.
mirrorX, param.
mirrorY);
}
public void render
(float _x,
float _y,
float _w,
float _h,
float _pivotX,
float _pivotY,
float _angle
)
{
render
(_x, _y, _w, _h, _pivotX, _pivotY, _angle, param.
mirrorX, param.
mirrorY);
}
public void render
(float _x,
float _y,
float _w,
float _h,
float _pivotX,
float _pivotY,
float _angle,
boolean _mirrorX,
boolean _mirrorY
)
{
SpriteShader shader = getGraphics
().
getSpriteShader();
RenderStates rs = getRenderStates
();
/* mScale.setScale(_w, _h, 1.0f);
mPivotTranslate.setTranslation(-param.pivotX, -param.pivotY, 0);
mMirror.setScale((param.mirrorX ? -1 : 1), (param.mirrorY ? -1 : 1), 1);
mRotateZ.setRotationZ(param.angle);
mTranslate.setTranslation(_x, _y, 0);
mModelMatrix.identity();
Matrix4.multiply(mModelMatrix, mScale, mPivotTranslate);
Matrix4.multiply(mModelMatrix, mModelMatrix, mMirror);
Matrix4.multiply(mModelMatrix, mModelMatrix, mRotateZ);
Matrix4.multiply(mModelMatrix, mModelMatrix, mTranslate);*/
mScale.
setScale(_w/
2, _h/
2, 1.0f
);
mPivotTranslate.
setTranslation(-_pivotX+_w/
2, -_pivotY+_h/
2,
0);
mMirror.
setScale((_mirrorX
? -
1 :
1),
(_mirrorY
? -
1 :
1),
1);
mRotateZ.
setRotationZ(_angle
);
mTranslate.
setTranslation(_x, _y,
0);
mModelMatrix.
identity();
Matrix4.
multiply(mModelMatrix, mModelMatrix, mMirror
);
Matrix4.
multiply(mModelMatrix, mModelMatrix, mScale
);
Matrix4.
multiply(mModelMatrix, mModelMatrix, mPivotTranslate
);
Matrix4.
multiply(mModelMatrix, mModelMatrix, mRotateZ
);
Matrix4.
multiply(mModelMatrix, mModelMatrix, mTranslate
);
rs.
pushModelMatrix();
{
rs.
model = mModelMatrix
;
// draw sprite
shader.
activate(mTexture, param.
alpha, param.
color);
{
rs.
blending.
setEnabled(true);
rs.
culling.
setEnabled(false);
rs.
activate();
{
mMesh.
render();
}
rs.
deactivate();
}
shader.
deactivate();
}
rs.
popModelMatrix();
}
/** Center the pivot. */
public void centerPivot
()
{
param.
pivotX = param.
w/2.0f
;
param.
pivotY = param.
h/2.0f
;
}
/** Get the sprite texture's total width. */
public final int getTextureWidth
()
{
if (mTexture ==
null)
return 0;
return mTexture.
getWidth();
}
/** Get the sprite texture's total height. */
public final int getTextureHeight
()
{
if (mTexture ==
null)
return 0;
return mTexture.
getHeight();
}
/** Get a reference to the texture. */
public final Texture getTexture
()
{
return mTexture
;
}
/** Set a new texture, with the old one (if any) getting destroyed. */
public final void setTexture
(Texture texture
)
{
if (mTexture
!=
null)
mTexture.
dispose();
mTexture = texture
;
}
/** Get the upper left corner as a Vector2. */
public Vector2 getTopLeft
()
{
return param.
getTopLeft();
}
/** Get the upper left corner as a Vector2. */
public Vector2 getTopRight
()
{
return param.
getTopRight();
}
/** Get the upper left corner as a Vector2. */
public Vector2 getBottomLeft
()
{
return param.
getBottomLeft();
}
/** Get the upper left corner as a Vector2. */
public Vector2 getBottomRight
()
{
return param.
getBottomRight();
}
/** Check if the point is inside the sprite. */
public boolean isInside
(float x,
float y
)
{
return isInside
(x, y
);
}
/** Check if the Sprite has been asynchronously loaded. */
public final boolean isAsync
() { return mIsAsync
; }
}