mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 16:54:22 +00:00
Further reduce quad count of generated item models (#4448)
This commit is contained in:
1 parent
f8e375279d
commit
43749d3fd1
13 files changed
+206
-87
No files matched your search
@@ -195,6 +195,7 @@ public final class ItemLayerModel implements IModel
|
||||
int vMax = sprite.getIconHeight();
|
||||
|
||||
FaceData faceData = new FaceData(uMax, vMax);
|
||||
boolean translucent = false;
|
||||
|
||||
for(int f = 0; f < sprite.getFrameCount(); f++)
|
||||
{
|
||||
@@ -207,7 +208,14 @@ public final class ItemLayerModel implements IModel
|
||||
ptu = true;
|
||||
for(int u = 0; u < uMax; u++)
|
||||
{
|
||||
boolean t = isTransparent(pixels, uMax, vMax, u, v);
|
||||
int alpha = getAlpha(pixels, uMax, vMax, u, v);
|
||||
boolean t = alpha == 0;
|
||||
|
||||
if (!t && alpha < 255)
|
||||
{
|
||||
translucent = true;
|
||||
}
|
||||
|
||||
if(ptu && !t) // left - transparent, right - opaque
|
||||
{
|
||||
faceData.set(EnumFacing.WEST, u, v);
|
||||
@@ -224,6 +232,7 @@ public final class ItemLayerModel implements IModel
|
||||
{
|
||||
faceData.set(EnumFacing.DOWN, u, v-1);
|
||||
}
|
||||
|
||||
ptu = t;
|
||||
ptv[u] = t;
|
||||
}
|
||||
@@ -247,29 +256,44 @@ public final class ItemLayerModel implements IModel
|
||||
{
|
||||
for (int v = 0; v < vMax; v++)
|
||||
{
|
||||
int uStart = 0;
|
||||
int uStart = 0, uEnd = uMax;
|
||||
boolean building = false;
|
||||
for (int u = 0; u < uMax; u++)
|
||||
{
|
||||
boolean face = faceData.get(facing, u, v);
|
||||
if (building && !face) // finish current quad
|
||||
if (!translucent)
|
||||
{
|
||||
// make quad [uStart, u]
|
||||
int off = facing == EnumFacing.DOWN ? 1 : 0;
|
||||
builder.add(buildSideQuad(format, transform, facing, tint, sprite, uStart, v+off, u-uStart));
|
||||
building = false;
|
||||
if (face)
|
||||
{
|
||||
if (!building)
|
||||
{
|
||||
building = true;
|
||||
uStart = u;
|
||||
}
|
||||
uEnd = u + 1;
|
||||
}
|
||||
}
|
||||
else if (!building && face) // start new quad
|
||||
else
|
||||
{
|
||||
building = true;
|
||||
uStart = u;
|
||||
if (building && !face) // finish current quad
|
||||
{
|
||||
// make quad [uStart, u]
|
||||
int off = facing == EnumFacing.DOWN ? 1 : 0;
|
||||
builder.add(buildSideQuad(format, transform, facing, tint, sprite, uStart, v+off, u-uStart));
|
||||
building = false;
|
||||
}
|
||||
else if (!building && face) // start new quad
|
||||
{
|
||||
building = true;
|
||||
uStart = u;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (building) // quad extends to far edge
|
||||
if (building) // build remaining quad
|
||||
{
|
||||
// make quad [uStart, uMax]
|
||||
// make quad [uStart, uEnd]
|
||||
int off = facing == EnumFacing.DOWN ? 1 : 0;
|
||||
builder.add(buildSideQuad(format, transform, facing, tint, sprite, uStart, v+off, uMax-uStart));
|
||||
builder.add(buildSideQuad(format, transform, facing, tint, sprite, uStart, v+off, uEnd-uStart));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,29 +303,44 @@ public final class ItemLayerModel implements IModel
|
||||
{
|
||||
for (int u = 0; u < uMax; u++)
|
||||
{
|
||||
int vStart = 0;
|
||||
int vStart = 0, vEnd = vMax;
|
||||
boolean building = false;
|
||||
for (int v = 0; v < vMax; v++)
|
||||
{
|
||||
boolean face = faceData.get(facing, u, v);
|
||||
if (building && !face) // finish current quad
|
||||
if (!translucent)
|
||||
{
|
||||
// make quad [vStart, v]
|
||||
int off = facing == EnumFacing.EAST ? 1 : 0;
|
||||
builder.add(buildSideQuad(format, transform, facing, tint, sprite, u+off, vStart, v-vStart));
|
||||
building = false;
|
||||
if (face)
|
||||
{
|
||||
if (!building)
|
||||
{
|
||||
building = true;
|
||||
vStart = v;
|
||||
}
|
||||
vEnd = v + 1;
|
||||
}
|
||||
}
|
||||
else if (!building && face) // start new quad
|
||||
else
|
||||
{
|
||||
building = true;
|
||||
vStart = v;
|
||||
if (building && !face) // finish current quad
|
||||
{
|
||||
// make quad [vStart, v]
|
||||
int off = facing == EnumFacing.EAST ? 1 : 0;
|
||||
builder.add(buildSideQuad(format, transform, facing, tint, sprite, u+off, vStart, v-vStart));
|
||||
building = false;
|
||||
}
|
||||
else if (!building && face) // start new quad
|
||||
{
|
||||
building = true;
|
||||
vStart = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (building) // quad extends to far edge
|
||||
if (building) // build remaining quad
|
||||
{
|
||||
// make quad [vStart, vMax]
|
||||
// make quad [vStart, vEnd]
|
||||
int off = facing == EnumFacing.EAST ? 1 : 0;
|
||||
builder.add(buildSideQuad(format, transform, facing, tint, sprite, u+off, vStart, vMax-vStart));
|
||||
builder.add(buildSideQuad(format, transform, facing, tint, sprite, u+off, vStart, vEnd-vStart));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -356,88 +395,55 @@ public final class ItemLayerModel implements IModel
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isTransparent(int[] pixels, int uMax, int vMax, int u, int v)
|
||||
private static int getAlpha(int[] pixels, int uMax, int vMax, int u, int v)
|
||||
{
|
||||
return (pixels[u + (vMax - 1 - v) * uMax] >> 24 & 0xFF) == 0;
|
||||
return pixels[u + (vMax - 1 - v) * uMax] >> 24 & 0xFF;
|
||||
}
|
||||
|
||||
private static BakedQuad buildSideQuad(VertexFormat format, Optional<TRSRTransformation> transform, EnumFacing side, int tint, TextureAtlasSprite sprite, int u, int v, int size)
|
||||
{
|
||||
final float eps0 = 30e-5f;
|
||||
final float eps1 = 45e-5f;
|
||||
final float eps2 = .5f;
|
||||
final float eps3 = .5f;
|
||||
float x0 = (float)u / sprite.getIconWidth();
|
||||
float y0 = (float)v / sprite.getIconHeight();
|
||||
final float eps = 1e-2f;
|
||||
|
||||
int width = sprite.getIconWidth();
|
||||
int height = sprite.getIconHeight();
|
||||
|
||||
float x0 = (float) u / width;
|
||||
float y0 = (float) v / height;
|
||||
float x1 = x0, y1 = y0;
|
||||
float z1 = 7.5f / 16f - eps1, z2 = 8.5f / 16f + eps1;
|
||||
float z0 = 7.5f / 16f, z1 = 8.5f / 16f;
|
||||
|
||||
switch(side)
|
||||
{
|
||||
case WEST:
|
||||
z1 = 8.5f / 16f + eps1;
|
||||
z2 = 7.5f / 16f - eps1;
|
||||
z0 = 8.5f / 16f;
|
||||
z1 = 7.5f / 16f;
|
||||
case EAST:
|
||||
y1 = (float) (v + size) / sprite.getIconHeight();
|
||||
y1 = (float) (v + size) / height;
|
||||
break;
|
||||
case DOWN:
|
||||
z1 = 8.5f / 16f + eps1;
|
||||
z2 = 7.5f / 16f - eps1;
|
||||
z0 = 8.5f / 16f;
|
||||
z1 = 7.5f / 16f;
|
||||
case UP:
|
||||
x1 = (float) (u + size) / sprite.getIconWidth();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("can't handle z-oriented side");
|
||||
}
|
||||
float u0 = 16f * (x0 - side.getDirectionVec().getX() * eps3 / sprite.getIconWidth());
|
||||
float u1 = 16f * (x1 - side.getDirectionVec().getX() * eps3 / sprite.getIconWidth());
|
||||
float v0 = 16f * (1f - y0 - side.getDirectionVec().getY() * eps3 / sprite.getIconHeight());
|
||||
float v1 = 16f * (1f - y1 - side.getDirectionVec().getY() * eps3 / sprite.getIconHeight());
|
||||
switch(side)
|
||||
{
|
||||
case WEST:
|
||||
case EAST:
|
||||
y0 -= eps1;
|
||||
y1 += eps1;
|
||||
v0 -= eps2 / sprite.getIconHeight();
|
||||
v1 += eps2 / sprite.getIconHeight();
|
||||
break;
|
||||
case DOWN:
|
||||
case UP:
|
||||
x0 -= eps1;
|
||||
x1 += eps1;
|
||||
u0 += eps2 / sprite.getIconWidth();
|
||||
u1 -= eps2 / sprite.getIconWidth();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("can't handle z-oriented side");
|
||||
}
|
||||
switch(side)
|
||||
{
|
||||
case WEST:
|
||||
x0 += eps0;
|
||||
x1 += eps0;
|
||||
break;
|
||||
case EAST:
|
||||
x0 -= eps0;
|
||||
x1 -= eps0;
|
||||
break;
|
||||
case DOWN:
|
||||
y0 -= eps0;
|
||||
y1 -= eps0;
|
||||
break;
|
||||
case UP:
|
||||
y0 += eps0;
|
||||
y1 += eps0;
|
||||
x1 = (float) (u + size) / width;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("can't handle z-oriented side");
|
||||
}
|
||||
|
||||
float dx = side.getDirectionVec().getX() * eps / width;
|
||||
float dy = side.getDirectionVec().getY() * eps / height;
|
||||
|
||||
float u0 = 16f * (x0 - dx);
|
||||
float u1 = 16f * (x1 - dx);
|
||||
float v0 = 16f * (1f - y0 - dy);
|
||||
float v1 = 16f * (1f - y1 - dy);
|
||||
|
||||
return buildQuad(
|
||||
format, transform, side.getOpposite(), sprite, tint, // getOpposite is related either to the swapping of V direction, or something else
|
||||
x0, y0, z1, sprite.getInterpolatedU(u0), sprite.getInterpolatedV(v0),
|
||||
x0, y0, z0, sprite.getInterpolatedU(u0), sprite.getInterpolatedV(v0),
|
||||
x1, y1, z0, sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1),
|
||||
x1, y1, z1, sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1),
|
||||
x1, y1, z2, sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1),
|
||||
x0, y0, z2, sprite.getInterpolatedU(u0), sprite.getInterpolatedV(v0)
|
||||
x0, y0, z1, sprite.getInterpolatedU(u0), sprite.getInterpolatedV(v0)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user