package com.gebauz.bauzoid.graphics.spritex;
import com.badlogic.gdx.Gdx;
import com.gebauz.bauzoid.graphics.Graphics;
import com.gebauz.bauzoid.graphics.model.SimpleGeometry;
import com.gebauz.bauzoid.graphics.model.Geometry.PrimitiveType;
import com.gebauz.bauzoid.graphics.renderstates.RenderStates;
import com.gebauz.bauzoid.graphics.sprite.SpriteShader;
import com.gebauz.bauzoid.math.Vector4;
/** Sprite atlas.
* Implements a sprite that defines multiple regions that can be used
* as Sprite Atlas or as Animated Sprite.
*
*/
public class AtlasSprite
extends Sprite
{
public static int NUM_INDICES_PER_REGION =
6;
public static int NUM_ATTRIBUTES_PER_REGION =
4;
/** Stores the seperate regions of the sprite. */
private SpriteRegion
[] mRegions =
null;
/** Stores all Geometry of all SpriteRegions. */
private SimpleGeometry mMesh =
null;
/** Stores a potential atlas definition file that should be loaded. */
private String mAtlasDefinitionFile =
null;
/** Constructor. */
public AtlasSprite
(Graphics graphics,
String textureFile
)
{
super(graphics, textureFile
);
}
public AtlasSprite
(Graphics graphics,
String textureFile,
String atlasFile
)
{
super(graphics, textureFile
);
mAtlasDefinitionFile = atlasFile
;
}
public void setRegions
(SpriteRegion
[] regions
)
{
if (mMesh
!=
null)
{
mMesh.
dispose();
mMesh =
null;
}
mRegions = regions
;
mMesh = createGeometry
();
}
@
Override
public void initAsync
()
{
super.
initAsync();
if (mAtlasDefinitionFile
!=
null)
{
getAssetManager
().
load(mAtlasDefinitionFile, AtlasDefinition.
class);
}
}
/** Called synchronously after initAsync() has been called. */
@
Override
public void init
(float _x,
float _y,
float _w,
float _h,
float _pivotX,
float _pivotY
)
{
super.
init(_x, _y, _w, _h, _pivotX, _pivotY
);
if (mAtlasDefinitionFile
!=
null)
{
AtlasDefinition atlas =
null;
if (!mIsAsync
)
{
// load synchronously
atlas = SpriteUtil.
readAtlasSpriteInfo(Gdx.
files.
internal(mAtlasDefinitionFile
));
}
else
{
atlas = getAssetManager
().
get(mAtlasDefinitionFile, AtlasDefinition.
class);
}
SpriteRegion regions
[] =
new SpriteRegion
[atlas.
frames.
size()];
for (int i =
0; i
< atlas.
frames.
size(); i++
)
{
AtlasDefinition.
FrameInfo info = atlas.
frames.
get(i
);
regions
[i
] =
new SpriteRegion
(getTexture
(), info.
x, info.
y, info.
w, info.
h);
}
setRegions
(regions
);
}
}
public void dispose
()
{
super.
dispose();
mRegions =
null;
if (mMesh
!=
null)
{
mMesh.
dispose();
mMesh =
null;
}
/* for (int i = 0; i < mGeometryCache.length; i++)
{
mGeometryCache[i].dispose();
mGeometryCache[i] = null;
}
mGeometryCache = null;*/
}
public SimpleGeometry createGeometry
()
{
float[] vertices =
new float[NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
POSITION_COORD_PER_ELEMENT * mRegions.
length];
float[] texCoords =
new float[NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
TEXCOORD_COORD_PER_ELEMENT * mRegions.
length];
float[] colors =
new float[NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
COLOR_COORD_PER_ELEMENT * mRegions.
length];
// two triangles per region
short[] indices =
new short[NUM_INDICES_PER_REGION
* mRegions.
length];
for (int i =
0; i
< mRegions.
length; i++
)
{
SpriteRegion r = getRegion
(i
);
/*float[] v =
{
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};*/
float[] v =
{
-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[] t =
{
r.
left, r.
top,
r.
right, r.
top,
r.
right, r.
bottom,
r.
left, r.
bottom
};
float[] c =
{
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
};
System.
arraycopy(v,
0, vertices, NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
POSITION_COORD_PER_ELEMENT * i, v.
length);
System.
arraycopy(t,
0, texCoords, NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
TEXCOORD_COORD_PER_ELEMENT * i, t.
length);
System.
arraycopy(c,
0, colors, NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
COLOR_COORD_PER_ELEMENT * i, c.
length);
int n = i
*NUM_INDICES_PER_REGION
;
short base =
(short)(i
* NUM_ATTRIBUTES_PER_REGION
);
indices
[n++
] = base
; indices
[n++
] =
(short)(base+
1); indices
[n++
] =
(short)(base+
2);
indices
[n++
] = base
; indices
[n++
] =
(short)(base+
2); indices
[n++
] =
(short)(base+
3);
}
SimpleGeometry mesh =
new SimpleGeometry
(getGraphics
(), PrimitiveType.
TRIANGLES);
mesh.
setPositions(vertices
);
mesh.
setTexCoords(texCoords
);
mesh.
setColors(colors
);
mesh.
setIndices(indices
);
return mesh
;
}
public final AtlasSpriteFrame createSpriteInstance
(int regionIndex
)
{
return new AtlasSpriteFrame
(this, regionIndex
);
}
public void createSpriteInstances
(AtlasSpriteFrame
[] instances
)
{
if (instances.
length < mRegions.
length)
return;
for (int i =
0; i
< instances.
length; i++
)
{
instances
[i
] = createSpriteInstance
(i
);
}
}
public AtlasSpriteFrame
[] createSpriteInstances
()
{
AtlasSpriteFrame frames
[] =
new AtlasSpriteFrame
[mRegions.
length];
createSpriteInstances
(frames
);
return frames
;
}
public void update
(float deltaTime
)
{
}
public void render
()
{
}
/*
@Deprecated
public void render(int regionIndex)
{
render(regionIndex, param.x, param.y, param.w, param.h);
}
@Deprecated
public void render(int regionIndex, float _x, float _y)
{
render(regionIndex, _x, _y, param.w, param.h);
}
@Deprecated
public void render(int regionIndex, float _x, float _y, float _w, float _h)
{
if (mRegions == null)
return;
RenderStates rs = getRenderStates();
Matrix4 modelMatrix = Matrix4.multiply(Matrix4.createScale(_w, _h, 1.0f), Matrix4.createTranslation(-param.pivotX, -param.pivotY, 0));
modelMatrix = Matrix4.multiply(modelMatrix, Matrix4.createScale((param.mirrorX ? -1 : 1), (param.mirrorY ? -1 : 1), 1));
modelMatrix = Matrix4.multiply(modelMatrix, Matrix4.createRotationZ(param.angle));
modelMatrix = Matrix4.multiply(modelMatrix, Matrix4.createTranslation(_x, _y, 0));
rs.pushModelMatrix();
{
rs.model = modelMatrix;
performRender(regionIndex, param.alpha, param.color);
}
rs.popModelMatrix();
}*/
/** Peforms the actual render without any model matrix handling. */
public void performRender
(int region,
float alpha, Vector4 color
)
{
RenderStates rs = getRenderStates
();
SpriteShader shader = getGraphics
().
getSpriteShader();
// draw sprite
shader.
activate(getTexture
(), alpha, color
);
{
rs.
blending.
setEnabled(true);
rs.
culling.
setEnabled(false);
//rs.scissor.setEnabled(true);
//rs.scissor.setScissor(100, 200, 280, 300);
rs.
activate();
rs.
blending.
activate(true);
{
//getMesh(regionIndex).render();
mMesh.
render(getMeshStartIndex
(region
), NUM_INDICES_PER_REGION
);
}
rs.
deactivate();
}
shader.
deactivate();
}
/** Set absolute coordinates for given region. */
public void setAbsolute
(int regionIndex,
float x,
float y,
float w,
float h
)
{
if ((mTexture ==
null) ||
(mRegions ==
null) ||
(regionIndex
>= mRegions.
length))
return;
if (mRegions
[regionIndex
] ==
null)
{
// create region
mRegions
[regionIndex
] =
new SpriteRegion
(x, y, w, h
);
return;
}
mRegions
[regionIndex
].
setAbsolute(mTexture, x, y, w, h
);
}
/** Get number of defined regions. */
public final int getRegionCount
()
{
if (mRegions ==
null)
return 0;
return mRegions.
length;
}
/** Get region. */
public final SpriteRegion getRegion
(int i
)
{
if (mRegions ==
null)
return null;
return mRegions
[i
];
}
/** Get a region's width. */
public final float getRegionWidth
(int i
)
{
if (mRegions ==
null)
return 0.0f
;
return (mRegions
[i
].
right - mRegions
[i
].
left) * mTexture.
getWidth();
}
/** Get a region's height. */
public final float getRegionHeight
(int i
)
{
if (mRegions ==
null)
return 0.0f
;
return (mRegions
[i
].
bottom - mRegions
[i
].
top) * mTexture.
getHeight();
}
/** Get cached mesh. */
/*public final SimpleGeometry getMesh(int regionIndex)
{
return mGeometryCache[regionIndex];
}*/
/** Get the Geometry. */
public final SimpleGeometry getMesh
()
{
return mMesh
;
}
/** Get starting index for region mesh rendering. */
public final int getMeshStartIndex
(int regionIndex
)
{
return (regionIndex
* NUM_INDICES_PER_REGION
);
}
}