aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/makamys/lodmod/renderer/ChunkMesh.java')
-rw-r--r--src/main/java/makamys/lodmod/renderer/ChunkMesh.java113
1 files changed, 106 insertions, 7 deletions
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)));