Added pre merge quads for more performance!!!!

This commit is contained in:
TomTheFurry
2022-05-01 16:05:05 +08:00
parent 031539bd31
commit 10943e0d7d
5 changed files with 94 additions and 59 deletions
@@ -211,19 +211,22 @@ public final class BufferQuad
// get the width of this quad in the relevant axis
short thisPerpendicularCompareWidth;
short thisParallelCompareWidth;
short otherPerpendicularCompareWidth;
short otherParallelCompareWidth;
if (mergeDirection == BufferMergeDirectionEnum.EastWest)
{
thisPerpendicularCompareWidth = this.widthEastWest;
thisParallelCompareWidth = this.widthNorthSouthOrUpDown;
otherPerpendicularCompareWidth = quad.widthEastWest;
otherParallelCompareWidth = quad.widthNorthSouthOrUpDown;
}
else
{
thisPerpendicularCompareWidth = this.widthNorthSouthOrUpDown;
thisParallelCompareWidth = this.widthEastWest;
otherPerpendicularCompareWidth = quad.widthNorthSouthOrUpDown;
otherParallelCompareWidth = quad.widthEastWest;
}
@@ -241,14 +244,15 @@ public final class BufferQuad
}
else if (thisPerpendicularCompareStartPos + thisPerpendicularCompareWidth > otherPerpendicularCompareStartPos)
{
// these quads are overlapping, they can't be merged
EVENT_LOGGER.warn("Overlapping quads detected!");
quad.hasError = true;
this.hasError = true;
if (thisPerpendicularCompareStartPos < otherPerpendicularCompareStartPos + otherPerpendicularCompareWidth) {
// these quads are overlapping, they can't be merged
//EVENT_LOGGER.warn("Overlapping quads detected!");
quad.hasError = true;
this.hasError = true;
}
return false;
}
// only merge quads that have the same width edges
if (thisParallelCompareWidth != otherParallelCompareWidth)
{
@@ -25,16 +25,20 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import com.seibel.lod.core.api.internal.EventApi;
import com.seibel.lod.core.api.internal.InternalApiShared;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.LodDirection.Axis;
import com.seibel.lod.core.enums.config.GpuUploadMethod;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.DhLoggerBuilder;
import com.seibel.lod.core.render.LodRenderer;
import com.seibel.lod.core.render.objects.GLVertexBuffer;
import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import net.minecraft.core.Direction;
import static com.seibel.lod.core.render.LodRenderer.EVENT_LOGGER;
@@ -163,7 +167,8 @@ public class LodQuadBuilder
},
};
private int premergeCount = 0;
public LodQuadBuilder(boolean enableSkylightCulling, int skyLightCullingBelow)
{
for (int i = 0; i < 6; i++)
@@ -184,7 +189,16 @@ public class LodQuadBuilder
throw new IllegalArgumentException("addQuadAdj() is only for adj direction! Not UP or Down!");
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
return;
quads[dir.ordinal()].add(new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, skylight, blocklight, dir));
BufferQuad quad = new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, skylight, blocklight, dir);
ArrayList<BufferQuad> qs = quads[dir.ordinal()];
if (!qs.isEmpty() &&
(qs.get(qs.size()-1).tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|| qs.get(qs.size()-1).tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
) {
premergeCount++;
return;
}
qs.add(quad);
}
// XZ
@@ -192,48 +206,34 @@ public class LodQuadBuilder
{
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
return;
quads[LodDirection.UP.ordinal()].add(new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, LodDirection.UP));
BufferQuad quad = new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, LodDirection.UP);
ArrayList<BufferQuad> qs = quads[LodDirection.UP.ordinal()];
if (!qs.isEmpty() &&
(qs.get(qs.size()-1).tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|| qs.get(qs.size()-1).tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
) {
premergeCount++;
return;
}
qs.add(quad);
}
public void addQuadDown(short x, short y, short z, short width, short wz, int color, byte skylight, byte blocklight)
{
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
return;
quads[LodDirection.DOWN.ordinal()].add(new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, LodDirection.DOWN));
}
// XY
public void addQuadN(short x, short y, short z, short width, short wy, int color, byte skylight, byte blocklight)
{
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
BufferQuad quad = new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, LodDirection.DOWN);
ArrayList<BufferQuad> qs = quads[LodDirection.DOWN.ordinal()];
if (!qs.isEmpty() &&
(qs.get(qs.size()-1).tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|| qs.get(qs.size()-1).tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
) {
premergeCount++;
return;
quads[LodDirection.NORTH.ordinal()].add(new BufferQuad(x, y, z, width, wy, color, skylight, blocklight, LodDirection.NORTH));
}
qs.add(quad);
}
public void addQuadS(short x, short y, short z, short width, short wy, int color, byte skylight, byte blocklight)
{
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
return;
quads[LodDirection.SOUTH.ordinal()].add(new BufferQuad(x, y, z, width, wy, color, skylight, blocklight, LodDirection.SOUTH));
}
// ZY
public void addQuadW(short x, short y, short z, short width, short wy, int color, byte skylight, byte blocklight)
{
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
return;
quads[LodDirection.WEST.ordinal()].add(new BufferQuad(x, y, z, width, wy, color, skylight, blocklight, LodDirection.WEST));
}
public void addQuadE(short x, short y, short z, short width, short wy, int color, byte skylight, byte blocklight)
{
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
return;
quads[LodDirection.EAST.ordinal()].add(new BufferQuad(x, y, z, width, wy, color, skylight, blocklight, LodDirection.EAST));
}
private static void putVertex(ByteBuffer bb, short x, short y, short z, int color, byte skylight, byte blocklight, int mx, int my, int mz)
{
skylight %= 16;
@@ -321,22 +321,22 @@ public class LodQuadBuilder
long preQuadsCount = getCurrentQuadsCount();
if (preQuadsCount <= 1)
return;
for (int directionIndex = 0; directionIndex < 6; directionIndex++)
{
mergeCount += mergeQuadsInternal(directionIndex, BufferMergeDirectionEnum.EastWest);
// only merge after the top has been merged
if (directionIndex == 1)
{
long pass2 = mergeQuadsInternal(directionIndex, BufferMergeDirectionEnum.NorthSouthOrUpDown);
mergeCount += pass2;
}
// only run the second merge if the face is the top or bottom
//if (directionIndex == LodDirection.UP.ordinal() || directionIndex == LodDirection.DOWN.ordinal())
//{
// long pass2 = mergeQuadsInternal(directionIndex, BufferMergeDirectionEnum.NorthSouthOrUpDown);
// mergeCount += pass2;
//}
}
long postQuadsCount = getCurrentQuadsCount();
//if (mergeCount != 0)
EVENT_LOGGER.debug("Merged {}/{}({}) quads", mergeCount, preQuadsCount, mergeCount / (double) preQuadsCount);
}
/** Merges all of this builder's quads for the given directionIndex (up, down, left, etc.) in the given direction */
private long mergeQuadsInternal(int directionIndex, BufferMergeDirectionEnum mergeDirection)
{
@@ -20,6 +20,7 @@
package com.seibel.lod.core.objects;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Arrays;
import com.seibel.lod.core.api.internal.InternalApiShared;
@@ -44,6 +45,14 @@ public class PosToRenderContainer
private int numberOfPosToRender;
private int[] posToRender;
private byte[][] population;
static class LodPos {
byte detail;
int posX;
int posZ;
}
private LodPos[] lodPosList;
public PosToRenderContainer(byte minDetail, int regionPosX, int regionPosZ)
{
@@ -54,6 +63,7 @@ public class PosToRenderContainer
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail);
posToRender = new int[size * size * 3];
population = new byte[size][size];
lodPosList = new LodPos[size * size];
}
public void addPosToRender(byte detailLevel, int posX, int posZ)
@@ -72,9 +82,13 @@ public class PosToRenderContainer
//if(numberOfPosToRender >= posToRender.length)
// posToRender = Arrays.copyOf(posToRender, posToRender.length*2);
posToRender[numberOfPosToRender * 3] = detailLevel;
posToRender[numberOfPosToRender * 3 + 1] = posX;
posToRender[numberOfPosToRender * 3 + 2] = posZ;
lodPosList[numberOfPosToRender] = new LodPos();
lodPosList[numberOfPosToRender].detail = detailLevel;
lodPosList[numberOfPosToRender].posX = posX;
lodPosList[numberOfPosToRender].posZ = posZ;
//posToRender[numberOfPosToRender * 3] = detailLevel;
//posToRender[numberOfPosToRender * 3 + 1] = posX;
//posToRender[numberOfPosToRender * 3 + 2] = posZ;
numberOfPosToRender++;
population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel, posX, minDetail))]
[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel, posZ, minDetail))] = (byte) (detailLevel + 1);
@@ -94,6 +108,7 @@ public class PosToRenderContainer
this.numberOfPosToRender = 0;
this.regionPosX = regionPosX;
this.regionPosZ = regionPosZ;
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail);
if (this.minDetail == minDetail)
{
Arrays.fill(posToRender, 0);
@@ -103,10 +118,10 @@ public class PosToRenderContainer
else
{
this.minDetail = minDetail;
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail);
posToRender = new int[size * size * 3];
population = new byte[size][size];
}
lodPosList = new LodPos[size * size];
}
public int getNumberOfPos()
@@ -116,19 +131,32 @@ public class PosToRenderContainer
public byte getNthDetailLevel(int n)
{
return (byte) posToRender[n * 3];
return lodPosList[n].detail;
//return (byte) posToRender[n * 3];
}
public int getNthPosX(int n)
{
return posToRender[n * 3 + 1];
return lodPosList[n].posX;
//return posToRender[n * 3 + 1];
}
public int getNthPosZ(int n)
{
return posToRender[n * 3 + 2];
return lodPosList[n].posZ;
//eturn posToRender[n * 3 + 2];
}
public void sort() {
Arrays.sort(lodPosList, 0, numberOfPosToRender,
(a,b) -> {
if (a.detail != b.detail) return a.detail - b.detail;
if (a.posX != b.posX) return a.posX - b.posX;
return a.posZ - b.posZ;
}
);
}
@Override
public String toString()
{
@@ -19,6 +19,7 @@
package com.seibel.lod.core.objects.lod;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicInteger;
@@ -29,6 +30,7 @@ import com.seibel.lod.core.enums.config.GenerationPriority;
import com.seibel.lod.core.enums.config.VerticalQuality;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.objects.LodDataView;
import com.seibel.lod.core.objects.Pos2D;
import com.seibel.lod.core.objects.PosToGenerateContainer;
import com.seibel.lod.core.objects.PosToRenderContainer;
import com.seibel.lod.core.util.DataPointUtil;
@@ -274,6 +274,7 @@ public class RenderRegion implements AutoCloseable
// position
PosToRenderContainer posToRender = new PosToRenderContainer(minDetail, region.regionPosX, region.regionPosZ);
region.getPosToRender(posToRender, playerX, playerZ);
posToRender.sort();
PosArrayGridList<BoolType> chunkGrid = ClientApi.renderer.vanillaChunks;
for (int index = 0; index < posToRender.getNumberOfPos(); index++) {