using
Microsoft.Xna.Framework;
using
Microsoft.Xna.Framework.Graphics;
namespace
Axios.Engine.Extenions
{
public
enum
TextureUnionLocation {
Right,
Bottom,
Top,
Left
}
public
static
class
AxiosExtensions_Texture2D
{
/// <summary>
/// Splits a texture into an array of smaller textures of the specified size.
/// </summary>
/// <param name="original">The texture to be split into smaller textures</param>
/// <param name="partWidth">The width of each of the smaller textures that will be contained in the returned array.</param>
/// <param name="partHeight">The height of each of the smaller textures that will be contained in the returned array.</param>
/// <returns>A multidimensional array represting the rows/coulmns in the texture.</returns>
public
static
Texture2D[,] Split(
this
Texture2D original,
int
partWidth,
int
partHeight,
out
int
xCount,
out
int
yCount)
{
yCount = original.Height / partHeight;
xCount = original.Width / partWidth;
Texture2D[,] r =
new
Texture2D[yCount,xCount];
int
dataPerPart = partWidth * partHeight;
Color[] originalData =
new
Color[original.Width * original.Height];
original.GetData<Color>(originalData);
int
currxidx = 0;
int
curryidx = 0;
for
(
int
y = 0; y < yCount * partHeight; y += partHeight)
{
for
(
int
x = 0; x < xCount * partWidth; x += partWidth)
{
Texture2D part =
new
Texture2D(original.GraphicsDevice, partWidth, partHeight);
Color[] partData =
new
Color[dataPerPart];
for
(
int
py = 0; py < partHeight; py++)
for
(
int
px = 0; px < partWidth; px++)
{
int
partIndex = px + py * partWidth;
if
(y + py >= original.Height || x + px >= original.Width)
partData[partIndex] = Color.Transparent;
else
partData[partIndex] = originalData[(x + px) + (y + py) * original.Width];
}
part.SetData<Color>(partData);
r[curryidx, currxidx] = part;
curryidx++;
}
curryidx = 0;
curryidx++;
}
return
r;
}
/// <summary>
/// Splits a texture into an array of smaller textures of the specified size.
/// </summary>
/// <param name="original">The texture to be split into smaller textures</param>
/// <param name="partWidth">The width of each of the smaller textures that will be contained in the returned array.</param>
/// <param name="partHeight">The height of each of the smaller textures that will be contained in the returned array.</param>
/// <param name="offsetWidth">The width offset whitespace to ignore</param>
/// <param name="offsetHeight">The height offset whitespace to ignore</param>
/// <param name="xCount">The number of textures per row</param>
/// <param name="yCount">The number of texture per column</param>
/// <returns>A multidimensional array represting the rows/coulmns in the texture.</returns>
public
static
Texture2D[,] Split(
this
Texture2D original,
int
partWidth,
int
partHeight,
int
offsetWidth,
int
offsetHeight,
out
int
xCount,
out
int
yCount)
{
yCount = original.Height / partHeight;
xCount = original.Width / partWidth;
Texture2D[,] r =
new
Texture2D[yCount, xCount];
int
dataPerPart = partWidth * partHeight;
Color[] originalData =
new
Color[original.Width * original.Height];
original.GetData<Color>(originalData);
int
currxidx = 0;
int
curryidx = 0;
for
(
int
y = 0; y < yCount * partHeight; y += (partHeight + offsetHeight))
{
for
(
int
x = 0; x < xCount * partWidth; x += (partWidth + offsetWidth))
{
Texture2D part =
new
Texture2D(original.GraphicsDevice, partWidth, partHeight);
Color[] partData =
new
Color[dataPerPart];
for
(
int
py = 0; py < partHeight; py++)
for
(
int
px = 0; px < partWidth; px++)
{
int
partIndex = px + py * partWidth;
if
(y + py >= original.Height || x + px >= original.Width)
partData[partIndex] = Color.Transparent;
else
partData[partIndex] = originalData[(x + px) + (y + py) * original.Width];
}
part.SetData<Color>(partData);
r[curryidx, currxidx] = part;
currxidx++;
}
currxidx = 0;
curryidx++;
}
return
r;
}
/// <summary>
/// Splits a texture into an array of smaller textures of the specified size.
/// </summary>
/// <param name="original">The texture to be split into smaller textures</param>
/// <param name="partWidth">The width of each of the smaller textures that will be contained in the returned array.</param>
/// <param name="partHeight">The height of each of the smaller textures that will be contained in the returned array.</param>
public
static
Texture2D[] SplitFlat(
this
Texture2D original,
int
partWidth,
int
partHeight,
out
int
xCount,
out
int
yCount)
{
yCount = original.Height / partHeight;
xCount = original.Width / partWidth;
Texture2D[] r =
new
Texture2D[xCount * yCount];
int
dataPerPart = partWidth * partHeight;
Color[] originalData =
new
Color[original.Width * original.Height];
original.GetData<Color>(originalData);
int
index = 0;
for
(
int
y = 0; y < yCount * partHeight; y += partHeight)
for
(
int
x = 0; x < xCount * partWidth; x += partWidth)
{
Texture2D part =
new
Texture2D(original.GraphicsDevice, partWidth, partHeight);
Color[] partData =
new
Color[dataPerPart];
for
(
int
py = 0; py < partHeight; py++)
for
(
int
px = 0; px < partWidth; px++)
{
int
partIndex = px + py * partWidth;
if
(y + py >= original.Height || x + px >= original.Width)
partData[partIndex] = Color.Transparent;
else
partData[partIndex] = originalData[(x + px) + (y + py) * original.Width];
}
part.SetData<Color>(partData);
r[index++] = part;
}
return
r;
}
/// <summary>
/// Splits a texture into an array of smaller textures of the specified size.
/// </summary>
/// <param name="original">The texture to be split into smaller textures</param>
/// <param name="partWidth">The width of each of the smaller textures that will be contained in the returned array.</param>
/// <param name="partHeight">The height of each of the smaller textures that will be contained in the returned array.</param>
public
static
Texture2D[] SplitFlat(
this
Texture2D original,
int
partWidth,
int
partHeight,
int
offsetWidth,
int
offsetHeight,
out
int
xCount,
out
int
yCount)
{
yCount = original.Height / partHeight;
xCount = original.Width / partWidth;
Texture2D[] r =
new
Texture2D[xCount * yCount];
int
dataPerPart = partWidth * partHeight;
Color[] originalData =
new
Color[original.Width * original.Height];
original.GetData<Color>(originalData);
int
index = 0;
for
(
int
y = 0; y < yCount * partHeight; y += (partHeight + offsetHeight))
for
(
int
x = 0; x < xCount * partWidth; x += (partWidth + offsetWidth))
{
Texture2D part =
new
Texture2D(original.GraphicsDevice, partWidth, partHeight);
Color[] partData =
new
Color[dataPerPart];
for
(
int
py = 0; py < partHeight; py++)
for
(
int
px = 0; px < partWidth; px++)
{
int
partIndex = px + py * partWidth;
if
(y + py >= original.Height || x + px >= original.Width)
partData[partIndex] = Color.Transparent;
else
partData[partIndex] = originalData[(x + px) + (y + py) * original.Width];
}
part.SetData<Color>(partData);
r[index++] = part;
}
return
r;
}
/// <summary>
/// Combines one texture with another
/// </summary>
/// <param name="original">The first texture</param>
/// <param name="texturetoadd">The second texture</param>
/// <param name="loc">The location where to put the texture in reference to the first</param>
/// <returns></returns>
public
static
Texture2D Union(
this
Texture2D original, Texture2D texturetoadd, TextureUnionLocation loc)
{
int
newWidth = 0;
int
newHeight = 0;
if
(loc == TextureUnionLocation.Right || loc == TextureUnionLocation.Left)
{
newWidth = original.Width + texturetoadd.Width;
newHeight = original.Height;
}
else
if
(loc == TextureUnionLocation.Bottom || loc == TextureUnionLocation.Top)
{
newWidth = original.Width;
newHeight = original.Height + texturetoadd.Height;
}
Texture2D r =
new
Texture2D(original.GraphicsDevice, newWidth, newHeight);
Color[] originaldata =
new
Color[original.Width * original.Height];
Color[] texturetoadddata =
new
Color[texturetoadd.Width * texturetoadd.Height];
Color[] newtexturedata =
new
Color[newHeight * newWidth];
original.GetData(originaldata);
texturetoadd.GetData(texturetoadddata);
if
(loc == TextureUnionLocation.Right)
{
r.SetData(0,
new
Rectangle(0, 0, original.Width, original.Height), originaldata, 0, original.Width * original.Height);
r.SetData(0,
new
Rectangle(original.Width, 0, texturetoadd.Width, texturetoadd.Height), texturetoadddata, 0, texturetoadd.Width * texturetoadd.Height);
}
else
if
(loc == TextureUnionLocation.Bottom)
{
r.SetData(0,
new
Rectangle(0, 0, original.Width, original.Height), originaldata, 0, original.Width * original.Height);
r.SetData(0,
new
Rectangle(0, original.Height, texturetoadd.Width, texturetoadd.Height), texturetoadddata, 0, texturetoadd.Width * texturetoadd.Height);
}
else
if
(loc == TextureUnionLocation.Left)
{
r.SetData(0,
new
Rectangle(0, 0, texturetoadd.Width, texturetoadd.Height), texturetoadddata, 0, texturetoadd.Width * texturetoadd.Height);
r.SetData(0,
new
Rectangle(texturetoadd.Width, 0, original.Width, original.Height), originaldata, 0, original.Width * original.Height);
}
else
if
(loc == TextureUnionLocation.Top)
{
r.SetData(0,
new
Rectangle(0, 0, texturetoadd.Width, texturetoadd.Height), texturetoadddata, 0, texturetoadd.Width * texturetoadd.Height);
r.SetData(0,
new
Rectangle(0, texturetoadd.Height, original.Width, original.Height), originaldata, 0, original.Width * original.Height);
}
return
r;
}
}
}