Added pre merge quads for more performance!!!!
This commit is contained in:
+12
-8
@@ -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)
|
||||
{
|
||||
|
||||
+43
-43
@@ -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++) {
|
||||
|
||||
Reference in New Issue
Block a user