Improved UV offset hackery - should fix most visible custom model seams.

This commit is contained in:
RainWarrior committed 2016-04-02 18:49:18 +03:00
1 parent c74216bdf2
commit 4c8da35655
5 files changed
+93 -1

No files matched your search

@@ -722,6 +722,7 @@ public enum B3DLoader implements ICustomModelLoader
for(Face f : faces)
{
UnpackedBakedQuad.Builder quadBuilder = new UnpackedBakedQuad.Builder(format);
quadBuilder.setContractUVs(true);
quadBuilder.setQuadOrientation(EnumFacing.getFacingFromVector(f.getNormal().x, f.getNormal().y, f.getNormal().z));
List<Texture> textures = null;
if(f.getBrush() != null) textures = f.getBrush().getTextures();
@@ -1403,6 +1403,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
sprite = ModelLoader.White.INSTANCE;
} else sprite = this.textures.get(f.getMaterialName());
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
builder.setContractUVs(true);
builder.setQuadOrientation(EnumFacing.getFacingFromVector(f.getNormal().x, f.getNormal().y, f.getNormal().z));
builder.setTexture(sprite);
Normal faceNormal = f.getNormal();
@@ -3,6 +3,7 @@ package net.minecraftforge.client.model.pipeline;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.EnumFacing;
// advantages: non-fixed-length vertex format, no overhead of packing and unpacking attributes to transform the model
@@ -75,6 +76,7 @@ public class UnpackedBakedQuad extends BakedQuad
private int vertices = 0;
private int elements = 0;
private boolean full = false;
private boolean contractUVs = false;
public Builder(VertexFormat format)
{
@@ -87,6 +89,10 @@ public class UnpackedBakedQuad extends BakedQuad
return format;
}
public void setContractUVs(boolean value)
{
this.contractUVs = value;
}
public void setQuadTint(int tint)
{
this.tint = tint;
@@ -132,12 +138,68 @@ public class UnpackedBakedQuad extends BakedQuad
}
}
private final float eps = 1f / 0x100;
public UnpackedBakedQuad build()
{
if(!full)
{
throw new IllegalStateException("not enough data");
}
if(contractUVs)
{
float tX = texture.getOriginX() / texture.getMinU();
float tY = texture.getOriginY() / texture.getMinV();
float tS = tX > tY ? tX : tY;
float ep = 1f / (tS * 0x100);
int uve = 0;
while(uve < format.getElementCount())
{
VertexFormatElement e = format.getElement(uve);
if(e.getUsage() == VertexFormatElement.EnumUsage.UV && e.getIndex() == 0)
{
break;
}
uve++;
}
if(uve == format.getElementCount())
{
throw new IllegalStateException("Can't contract UVs: format doesn't contain UVs");
}
float[] uvc = new float[4];
for(int v = 0; v < 4; v++)
{
for(int i = 0; i < 4; i++)
{
uvc[i] += unpackedData[v][uve][i] / 4;
}
}
for(int v = 0; v < 4; v++)
{
for (int i = 0; i < 4; i++)
{
float uo = unpackedData[v][uve][i];
float un = uo * (1 - eps) + uvc[i] * eps;
float ud = uo - un;
float aud = ud;
if(aud < 0) aud = -aud;
if(aud < ep) // not moving a fraction of a pixel
{
float udc = uo - uvc[i];
if(udc < 0) udc = -udc;
if(udc < 2 * ep) // center is closer than 2 fractions of a pixel, don't move too close
{
un = (uo + uvc[i]) / 2;
}
else // move at least by a fraction
{
un = uo + (ud < 0 ? ep : -ep);
}
}
unpackedData[v][uve][i] = un;
}
}
}
return new UnpackedBakedQuad(unpackedData, tint, orientation, texture, applyDiffuseLighting, format);
}
}