diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/FaceBakery.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/FaceBakery.java.patch index 8e298ade1d..f27905bd1c 100644 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/FaceBakery.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/block/model/FaceBakery.java.patch @@ -70,6 +70,17 @@ this.func_178404_a(p_188015_1_, j, p_188015_2_, vector3f, i, p_188015_6_, p_188015_4_); } +@@ -139,8 +155,8 @@ + p_178404_1_[i + 1] = Float.floatToRawIntBits(p_178404_4_.y); + p_178404_1_[i + 2] = Float.floatToRawIntBits(p_178404_4_.z); + p_178404_1_[i + 3] = p_178404_5_; +- p_178404_1_[i + 4] = Float.floatToRawIntBits(p_178404_6_.func_94214_a((double)p_178404_7_.func_178348_a(p_178404_3_))); +- p_178404_1_[i + 4 + 1] = Float.floatToRawIntBits(p_178404_6_.func_94207_b((double)p_178404_7_.func_178346_b(p_178404_3_))); ++ p_178404_1_[i + 4] = Float.floatToRawIntBits(p_178404_6_.func_94214_a((double)p_178404_7_.func_178348_a(p_178404_3_) * .999 + p_178404_7_.func_178348_a((p_178404_3_ + 2) % 4) * .001)); ++ p_178404_1_[i + 4 + 1] = Float.floatToRawIntBits(p_178404_6_.func_94207_b((double)p_178404_7_.func_178346_b(p_178404_3_) * .999 + p_178404_7_.func_178346_b((p_178404_3_ + 2) % 4) * .001)); + } + + private void func_178407_a(Vector3f p_178407_1_, BlockPartRotation p_178407_2_) @@ -189,14 +205,19 @@ public int func_188011_a(Vector3f p_188011_1_, EnumFacing p_188011_2_, int p_188011_3_, ModelRotation p_188011_4_) diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch index 5ef4028b9d..b7a16e4ae0 100644 --- a/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch @@ -1,6 +1,23 @@ --- ../src-base/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java +++ ../src-work/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java -@@ -398,4 +398,30 @@ +@@ -50,12 +50,10 @@ + this.field_110975_c = p_110971_3_; + this.field_110974_d = p_110971_4_; + this.field_130222_e = p_110971_5_; +- float f = (float)(0.009999999776482582D / (double)p_110971_1_); +- float f1 = (float)(0.009999999776482582D / (double)p_110971_2_); +- this.field_110979_l = (float)p_110971_3_ / (float)((double)p_110971_1_) + f; +- this.field_110980_m = (float)(p_110971_3_ + this.field_130223_c) / (float)((double)p_110971_1_) - f; +- this.field_110977_n = (float)p_110971_4_ / (float)p_110971_2_ + f1; +- this.field_110978_o = (float)(p_110971_4_ + this.field_130224_d) / (float)p_110971_2_ - f1; ++ this.field_110979_l = (float)p_110971_3_ / (float)p_110971_1_; ++ this.field_110980_m = (float)(p_110971_3_ + this.field_130223_c) / (float)p_110971_1_; ++ this.field_110977_n = (float)p_110971_4_ / (float)p_110971_2_; ++ this.field_110978_o = (float)(p_110971_4_ + this.field_130224_d) / (float)p_110971_2_; + } + + public void func_94217_a(TextureAtlasSprite p_94217_1_) +@@ -398,4 +396,30 @@ { return "TextureAtlasSprite{name=\'" + this.field_110984_i + '\'' + ", frameCount=" + this.field_110976_a.size() + ", rotated=" + this.field_130222_e + ", x=" + this.field_110975_c + ", y=" + this.field_110974_d + ", height=" + this.field_130224_d + ", width=" + this.field_130223_c + ", u0=" + this.field_110979_l + ", u1=" + this.field_110980_m + ", v0=" + this.field_110977_n + ", v1=" + this.field_110978_o + '}'; } diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java b/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java index 4b8095dd05..02f92be5de 100644 --- a/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java +++ b/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java @@ -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 textures = null; if(f.getBrush() != null) textures = f.getBrush().getTextures(); diff --git a/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java b/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java index 3efab8d738..4aba8091c3 100644 --- a/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java +++ b/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java @@ -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(); diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java b/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java index ac888e12a9..fae9806e3d 100644 --- a/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java +++ b/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java @@ -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); } }