aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormakamys <makamys@outlook.com>2022-06-06 16:51:10 +0200
committermakamys <makamys@outlook.com>2022-06-06 16:51:10 +0200
commit04535cc8889a111b5442555872a380e09855a5b7 (patch)
treec77b94ba9a64983b300a3b60b4eea4adaacd61e2 /src
parent4b0e58d288dede21c466bba941abd2b2d9719364 (diff)
downloadNeodymium-04535cc8889a111b5442555872a380e09855a5b7.tar.gz
Neodymium-04535cc8889a111b5442555872a380e09855a5b7.tar.bz2
Neodymium-04535cc8889a111b5442555872a380e09855a5b7.zip
Move Tessellator#toChunkMesh to ChunkMesh class
Diffstat (limited to 'src')
-rw-r--r--src/main/java/makamys/lodmod/MixinConfigPlugin.java1
-rw-r--r--src/main/java/makamys/lodmod/ducks/ITessellator.java11
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinTessellator.java171
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java3
-rw-r--r--src/main/java/makamys/lodmod/renderer/ChunkMesh.java113
-rw-r--r--src/main/resources/META-INF/LODMod_at.cfg9
6 files changed, 115 insertions, 193 deletions
diff --git a/src/main/java/makamys/lodmod/MixinConfigPlugin.java b/src/main/java/makamys/lodmod/MixinConfigPlugin.java
index 4d9fed1..be8ac7c 100644
--- a/src/main/java/makamys/lodmod/MixinConfigPlugin.java
+++ b/src/main/java/makamys/lodmod/MixinConfigPlugin.java
@@ -42,7 +42,6 @@ public class MixinConfigPlugin implements IMixinConfigPlugin {
mixins.addAll(Arrays.asList("MixinChunkCache",
"MixinEntityRenderer",
"MixinRenderGlobal",
- "MixinTessellator",
"MixinWorldRenderer",
"MixinRenderBlocks"));
diff --git a/src/main/java/makamys/lodmod/ducks/ITessellator.java b/src/main/java/makamys/lodmod/ducks/ITessellator.java
deleted file mode 100644
index eb8f90a..0000000
--- a/src/main/java/makamys/lodmod/ducks/ITessellator.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package makamys.lodmod.ducks;
-
-import org.spongepowered.asm.mixin.Mixin;
-
-import makamys.lodmod.renderer.ChunkMesh;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.WorldRenderer;
-
-public interface ITessellator {
- public ChunkMesh toChunkMesh(int pass, WorldRenderer wr);
-}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinTessellator.java b/src/main/java/makamys/lodmod/mixin/MixinTessellator.java
deleted file mode 100644
index 08d220a..0000000
--- a/src/main/java/makamys/lodmod/mixin/MixinTessellator.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package makamys.lodmod.mixin;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-
-import makamys.lodmod.LODMod;
-import makamys.lodmod.MixinConfigPlugin;
-import makamys.lodmod.ducks.ITessellator;
-import makamys.lodmod.renderer.ChunkMesh;
-import makamys.lodmod.renderer.MeshQuad;
-import makamys.lodmod.renderer.MeshQuad.QuadPlaneComparator;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.WorldRenderer;
-
-@Mixin(Tessellator.class)
-abstract class MixinTessellator implements ITessellator {
-
- @Shadow
- private int vertexCount;
-
- @Shadow
- private int[] rawBuffer;
-
- @Shadow
- private double xOffset;
- @Shadow
- private double yOffset;
- @Shadow
- private double zOffset;
-
- @Shadow
- private boolean hasTexture;
- @Shadow
- private boolean hasBrightness;
- @Shadow
- private boolean hasColor;
- @Shadow
- private boolean hasNormals;
-
- private static int totalOriginalQuadCount = 0;
- private static int totalSimplifiedQuadCount = 0;
- /*
- public static void endSave() {
- if(out == null) {
- return;
- }
- try {
- out.close();
- String nameList = String.join("\n", ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites.keySet());
- Files.write(nameList, new File("tessellator_strings.txt"), Charset.forName("UTF-8"));
- out = null;
- } catch (IOException e) {
- e.printStackTrace();
- }
- }*/
-
- public ChunkMesh toChunkMesh(int pass, WorldRenderer wr) {
- if(this.vertexCount % 4 != 0) {
- System.out.println("Error: Vertex count is not a multiple of 4");
- return null;
- }
-
- List<MeshQuad> quads = new ArrayList<>();
-
- List<Integer> spriteIndexes = new ArrayList<>();
- List<Byte> xs = new ArrayList<>();
- List<Byte> ys = new ArrayList<>();
- List<Byte> zs = new ArrayList<>();
- List<Byte> relUs = new ArrayList<>();
- List<Byte> relVs = new ArrayList<>();
- List<Byte> bUs = new ArrayList<>();
- List<Byte> bVs = new ArrayList<>();
- List<Integer> cs = new ArrayList<>();
-
- int xOffset = wr.posX;
- int yOffset = wr.posY;
- int zOffset = wr.posZ;
-
- for(int quadI = 0; quadI < this.vertexCount / 4; quadI++) {
- boolean fr = MixinConfigPlugin.isOptiFinePresent() && LODMod.ofFastRender;
- MeshQuad quad = new MeshQuad(rawBuffer, quadI * 32, new ChunkMesh.Flags(hasTexture, hasBrightness, hasColor, hasNormals), fr ? xOffset : 0, fr ? yOffset : 0, fr ? zOffset : 0);
- /*if(quad.bUs[0] == quad.bUs[1] && quad.bUs[1] == quad.bUs[2] && quad.bUs[2] == quad.bUs[3] && quad.bUs[3] == quad.bVs[0] && quad.bVs[0] == quad.bVs[1] && quad.bVs[1] == quad.bVs[2] && quad.bVs[2] == quad.bVs[3] && quad.bVs[3] == 0) {
- quad.deleted = true;
- }*/
- if(quad.plane == quad.PLANE_XZ && !quad.isClockwiseXZ()) {
- // water hack
- quad.deleted = true;
- }
- quads.add(quad);
- }
- boolean optimize = LODMod.optimizeChunkMeshes;
- if(optimize) {
- ArrayList<ArrayList<MeshQuad>> quadsByPlaneDir = new ArrayList<>(); // XY, XZ, YZ
- for(int i = 0; i < 3; i++) {
- quadsByPlaneDir.add(new ArrayList<MeshQuad>());
- }
- for(MeshQuad quad : quads) {
- if(quad.plane != MeshQuad.PLANE_NONE) {
- quadsByPlaneDir.get(quad.plane).add(quad);
- }
- }
- for(int plane = 0; plane < 3; plane++) {
- quadsByPlaneDir.get(plane).sort(MeshQuad.QuadPlaneComparator.quadPlaneComparators[plane]);
- }
-
- for(int plane = 0; plane < 3; plane++) {
- List<MeshQuad> planeDirQuads = quadsByPlaneDir.get(plane);
- int planeStart = 0;
- for(int quadI = 0; quadI < planeDirQuads.size(); quadI++) {
- MeshQuad quad = planeDirQuads.get(quadI);
- MeshQuad nextQuad = quadI == planeDirQuads.size() - 1 ? null : planeDirQuads.get(quadI + 1);
- if(!quad.onSamePlaneAs(nextQuad)) {
- simplifyPlane(planeDirQuads.subList(planeStart, quadI));
- planeStart = quadI + 1;
- }
- }
- }
- }
-
- int quadCount = countValidQuads(quads);
-
- totalOriginalQuadCount += quads.size();
- totalSimplifiedQuadCount += quadCount;
- //System.out.println("simplified quads " + totalOriginalQuadCount + " -> " + totalSimplifiedQuadCount + " (ratio: " + ((float)totalSimplifiedQuadCount / (float)totalOriginalQuadCount) + ") totalMergeCountByPlane: " + Arrays.toString(totalMergeCountByPlane));
-
- LODMod.debugHookToChunkMeshEnd();
-
- if(quadCount > 0) {
- return new ChunkMesh(
- (int)(xOffset / 16), (int)(yOffset / 16), (int)(zOffset / 16),
- new ChunkMesh.Flags(hasTexture, hasBrightness, hasColor, hasNormals),
- quadCount, quads, pass);
- } else {
- return null;
- }
- }
-
- private void simplifyPlane(List<MeshQuad> planeQuads) {
- MeshQuad lastQuad = null;
- // Pass 1: merge quads to create rows
- for(MeshQuad quad : planeQuads) {
- if(lastQuad != null) {
- lastQuad.tryToMerge(quad);
- }
- if(quad.isValid(quad)) {
- lastQuad = quad;
- }
- }
-
- // Pass 2: merge rows to create rectangles
- // TODO optimize?
- for(int i = 0; i < planeQuads.size(); i++) {
- for(int j = i + 1; j < planeQuads.size(); j++) {
- planeQuads.get(i).tryToMerge(planeQuads.get(j));
- }
- }
- }
-
- private int countValidQuads(List<MeshQuad> quads) {
- int quadCount = 0;
- for(MeshQuad quad : quads) {
- if(!quad.deleted) {
- quadCount++;
- }
- }
- return quadCount;
- }
-}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java b/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java
index 7caecb1..791f24d 100644
--- a/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java
+++ b/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java
@@ -13,7 +13,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import makamys.lodmod.LODMod;
-import makamys.lodmod.ducks.ITessellator;
import makamys.lodmod.ducks.IWorldRenderer;
import makamys.lodmod.renderer.ChunkMesh;
import makamys.lodmod.renderer.FarChunkCache;
@@ -101,7 +100,7 @@ abstract class MixinWorldRenderer implements IWorldRenderer {
private void prePostRenderBlocks(int pass, EntityLivingBase entity, CallbackInfo ci) {
if(LODMod.isActive() && !LODMod.disableChunkMeshes) {
if(chunkMeshes != null) {
- chunkMeshes.add(((ITessellator)Tessellator.instance).toChunkMesh(pass, WorldRenderer.class.cast(this)));
+ chunkMeshes.add(ChunkMesh.fromTessellator(pass, WorldRenderer.class.cast(this), Tessellator.instance));
}
}
}
diff --git a/src/main/java/makamys/lodmod/renderer/ChunkMesh.java b/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
index 562aa49..928f63b 100644
--- a/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
+++ b/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
@@ -1,19 +1,13 @@
package makamys.lodmod.renderer;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -21,6 +15,7 @@ import java.util.stream.Collectors;
import org.lwjgl.BufferUtils;
import makamys.lodmod.LODMod;
+import makamys.lodmod.MixinConfigPlugin;
import makamys.lodmod.ducks.IWorldRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
@@ -30,7 +25,6 @@ import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByteArray;
-import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
public class ChunkMesh extends Mesh {
@@ -68,6 +62,111 @@ public class ChunkMesh extends Mesh {
this.nbtData = toNBT(quads, quadCount);
instances++;
}
+
+ private static int totalOriginalQuadCount = 0;
+ private static int totalSimplifiedQuadCount = 0;
+
+ public static ChunkMesh fromTessellator(int pass, WorldRenderer wr, Tessellator t) {
+ if(t.vertexCount % 4 != 0) {
+ System.out.println("Error: Vertex count is not a multiple of 4");
+ return null;
+ }
+
+ List<MeshQuad> quads = new ArrayList<>();
+
+ int xOffset = wr.posX;
+ int yOffset = wr.posY;
+ int zOffset = wr.posZ;
+
+ for(int quadI = 0; quadI < t.vertexCount / 4; quadI++) {
+ boolean fr = MixinConfigPlugin.isOptiFinePresent() && LODMod.ofFastRender;
+ MeshQuad quad = new MeshQuad(t.rawBuffer, quadI * 32, new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals), fr ? xOffset : 0, fr ? yOffset : 0, fr ? zOffset : 0);
+ /*if(quad.bUs[0] == quad.bUs[1] && quad.bUs[1] == quad.bUs[2] && quad.bUs[2] == quad.bUs[3] && quad.bUs[3] == quad.bVs[0] && quad.bVs[0] == quad.bVs[1] && quad.bVs[1] == quad.bVs[2] && quad.bVs[2] == quad.bVs[3] && quad.bVs[3] == 0) {
+ quad.deleted = true;
+ }*/
+ if(quad.plane == quad.PLANE_XZ && !quad.isClockwiseXZ()) {
+ // water hack
+ quad.deleted = true;
+ }
+ quads.add(quad);
+ }
+ boolean optimize = LODMod.optimizeChunkMeshes;
+ if(optimize) {
+ ArrayList<ArrayList<MeshQuad>> quadsByPlaneDir = new ArrayList<>(); // XY, XZ, YZ
+ for(int i = 0; i < 3; i++) {
+ quadsByPlaneDir.add(new ArrayList<MeshQuad>());
+ }
+ for(MeshQuad quad : quads) {
+ if(quad.plane != MeshQuad.PLANE_NONE) {
+ quadsByPlaneDir.get(quad.plane).add(quad);
+ }
+ }
+ for(int plane = 0; plane < 3; plane++) {
+ quadsByPlaneDir.get(plane).sort(MeshQuad.QuadPlaneComparator.quadPlaneComparators[plane]);
+ }
+
+ for(int plane = 0; plane < 3; plane++) {
+ List<MeshQuad> planeDirQuads = quadsByPlaneDir.get(plane);
+ int planeStart = 0;
+ for(int quadI = 0; quadI < planeDirQuads.size(); quadI++) {
+ MeshQuad quad = planeDirQuads.get(quadI);
+ MeshQuad nextQuad = quadI == planeDirQuads.size() - 1 ? null : planeDirQuads.get(quadI + 1);
+ if(!quad.onSamePlaneAs(nextQuad)) {
+ simplifyPlane(planeDirQuads.subList(planeStart, quadI));
+ planeStart = quadI + 1;
+ }
+ }
+ }
+ }
+
+ int quadCount = countValidQuads(quads);
+
+ totalOriginalQuadCount += quads.size();
+ totalSimplifiedQuadCount += quadCount;
+ //System.out.println("simplified quads " + totalOriginalQuadCount + " -> " + totalSimplifiedQuadCount + " (ratio: " + ((float)totalSimplifiedQuadCount / (float)totalOriginalQuadCount) + ") totalMergeCountByPlane: " + Arrays.toString(totalMergeCountByPlane));
+
+ LODMod.debugHookToChunkMeshEnd();
+
+ if(quadCount > 0) {
+ return new ChunkMesh(
+ (int)(xOffset / 16), (int)(yOffset / 16), (int)(zOffset / 16),
+ new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals),
+ quadCount, quads, pass);
+ } else {
+ return null;
+ }
+ }
+
+ private static void simplifyPlane(List<MeshQuad> planeQuads) {
+ MeshQuad lastQuad = null;
+ // Pass 1: merge quads to create rows
+ for(MeshQuad quad : planeQuads) {
+ if(lastQuad != null) {
+ lastQuad.tryToMerge(quad);
+ }
+ if(quad.isValid(quad)) {
+ lastQuad = quad;
+ }
+ }
+
+ // Pass 2: merge rows to create rectangles
+ // TODO optimize?
+ for(int i = 0; i < planeQuads.size(); i++) {
+ for(int j = i + 1; j < planeQuads.size(); j++) {
+ planeQuads.get(i).tryToMerge(planeQuads.get(j));
+ }
+ }
+ }
+
+ private static int countValidQuads(List<MeshQuad> quads) {
+ int quadCount = 0;
+ for(MeshQuad quad : quads) {
+ if(!quad.deleted) {
+ quadCount++;
+ }
+ }
+ return quadCount;
+ }
private NBTBase toNBT(List<MeshQuad> quads, int quadCount) {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream(quadCount * (2 + 4 * (3 + 2 + 2 + 4)));
diff --git a/src/main/resources/META-INF/LODMod_at.cfg b/src/main/resources/META-INF/LODMod_at.cfg
index 766965a..9c62e27 100644
--- a/src/main/resources/META-INF/LODMod_at.cfg
+++ b/src/main/resources/META-INF/LODMod_at.cfg
@@ -3,4 +3,11 @@ public net.minecraft.client.renderer.Tessellator func_78379_d()V #reset
public net.minecraft.world.biome.BiomeGenBase field_150605_ac #temperatureNoise
public net.minecraft.client.multiplayer.PlayerControllerMP field_78774_b #netClientHandler
-public net.minecraft.client.network.NetHandlerPlayClient field_147309_h #doneLoadingTerrain \ No newline at end of file
+public net.minecraft.client.network.NetHandlerPlayClient field_147309_h #doneLoadingTerrain
+
+public net.minecraft.client.renderer.Tessellator field_78406_i #vertexCount
+public net.minecraft.client.renderer.Tessellator field_78405_h #rawBuffer
+public net.minecraft.client.renderer.Tessellator field_78400_o #hasTexture
+public net.minecraft.client.renderer.Tessellator field_78414_p #hasBrightness
+public net.minecraft.client.renderer.Tessellator field_78399_n #hasColor
+public net.minecraft.client.renderer.Tessellator field_78413_q #hasNormals