From 5a6819757ba8081801eacfe783aea457ea49a6e6 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 2 Dec 2024 20:26:27 +1000 Subject: [PATCH] Very fast scanline mesher --- .../voxy/client/core/util/ScanMesher2D.java | 211 +++++++++++++----- 1 file changed, 155 insertions(+), 56 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/util/ScanMesher2D.java b/src/main/java/me/cortex/voxy/client/core/util/ScanMesher2D.java index 44a56a10..d92d4baf 100644 --- a/src/main/java/me/cortex/voxy/client/core/util/ScanMesher2D.java +++ b/src/main/java/me/cortex/voxy/client/core/util/ScanMesher2D.java @@ -1,10 +1,12 @@ package me.cortex.voxy.client.core.util; -public class ScanMesher2D { +import java.util.Random; + +public abstract class ScanMesher2D { // is much faster if implemented inline into parent - private long[] rowData = new long[32]; - private int[] rowLength = new int[32];//How long down does a row entry go - private int[] rowDepth = new int[32];//How many rows does it cover + private final long[] rowData = new long[32]; + private final int[] rowLength = new int[32];//How long down does a row entry go + private final int[] rowDepth = new int[32];//How many rows does it cover private int rowBitset = 0; int currentIndex = 0; @@ -13,12 +15,12 @@ public class ScanMesher2D { //Two different ways to do it, scanline then only merge on change, or try to merge with previous row at every step // or even can also attempt to merge previous but if the lengths are different split the current one and merge to previous - public void putNext(long data) { - int thisIdx = (this.currentIndex++)&31;//Mask to current row, but keep total so can compute actual indexing + public final void putNext(long data) { + int idx = (this.currentIndex++)&31;//Mask to current row, but keep total so can compute actual indexing //If we are on the zero index, ignore it as we are going from empty state to maybe something state // setup data - if (thisIdx == 0) { + if (idx == 0) { //If the previous data is not zero, that means it was not merge-able, so emit it at the pos if (this.currentData!=0) { if ((this.rowBitset&(1<<31))!=0) { @@ -35,59 +37,39 @@ public class ScanMesher2D { this.currentSum = 0; } - //If we are the same as last data increment - if (data == this.currentData) { - this.currentSum++; - //If we merge, then just continue - this.mergeCurrentIfPossibleOrEmit(thisIdx); - return; - } - - //write out previous data - if (this.currentData != 0) { - int prev = thisIdx-1;//We need to write in the previous entry - this.rowDepth[prev] = 1; - this.rowLength[prev] = this.currentSum; - this.rowData[prev] = this.currentData; - this.rowBitset |= 1<>5, v); + j++; + } + m2.process(); + } + + long t = System.nanoTime(); + for (int i = 0; i < 1000000; i++) { + for (long v : data) { + mesher.putNext(v); + } + mesher.endPush(); + } + long delta = System.nanoTime()-t; + System.out.println(delta*1e-6); + + + t = System.nanoTime(); + for (int i = 0; i < 1000000; i++) { + int j = 0; + m2.reset(); + for (long v : data) { + if (v!=0) + m2.put(j&31, j>>5, v); + j++; + } + m2.process(); + } + delta = System.nanoTime()-t; + System.out.println(delta*1e-6); + + + } + public static void main3(String[] args) { + var r = new Random(0); + int[] qc = new int[2]; + var mesher = new ScanMesher2D(){ + @Override + protected void emitQuad(int length, int width, long data) { + qc[0]++; + qc[1]+=length*width; + } + }; + + var mesh2 = new Mesher2D(); + + float DENSITY = 0.5f; + int RANGE = 50; + int total = 0; + while (true) { + DENSITY = r.nextFloat(); + RANGE = r.nextInt(500)+1; + qc[0] = 0; qc[1] = 0; + int c = 0; + for (int i = 0; i < 32*32; i++) { + long val = r.nextFloat()>5, val); + } + } + mesher.endPush(); + if (c != qc[1]) { + System.out.println(c+", " + qc[1]); + } + int count = mesh2.process(); + int delta = count - qc[0]; + total += delta; + System.out.println(total); + //System.out.println(c+", new: " + qc[0] + " old: " + count); + } + } + + public static void main2(String[] args) { long[] sample = new long[32*32]; sample[0] = 1; @@ -130,9 +221,17 @@ public class ScanMesher2D { sample[7+32*1] = 2; sample[31+32*0] = 6; sample[31+32*1] = 6; + sample[30+32*2] = 7; sample[31+32*2] = 7; - sample[31+32*3] = 8; - var mesher = new ScanMesher2D(); + sample[30+32*3] = 7; + sample[31+32*3] = 7; + sample[31+32*8] = 8; + var mesher = new ScanMesher2D() { + @Override + protected void emitQuad(int length, int width, long data) { + System.out.println(length + ", " + width + ", " + data); + } + }; int j = 0; for (long i : sample) { if (j%32 == 0) {