Added dataView system so no longer need to copy arrays around
This commit is contained in:
+3
-2
@@ -21,6 +21,7 @@ package com.seibel.lod.core.builders.lodBuilding.bufferBuilding;
|
||||
|
||||
import com.seibel.lod.core.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
||||
import com.seibel.lod.core.objects.LodDataView;
|
||||
import com.seibel.lod.core.objects.opengl.LodBox;
|
||||
import com.seibel.lod.core.util.ColorUtil;
|
||||
import com.seibel.lod.core.util.DataPointUtil;
|
||||
@@ -37,8 +38,8 @@ public class CubicLodTemplate
|
||||
{
|
||||
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
|
||||
|
||||
public static void addLodToBuffer(long data, long topData, long botData, long[][][] adjData,
|
||||
boolean[] adjFillBlack, byte detailLevel,int offsetPosX, int offsetOosZ, LodQuadBuilder quadBuilder, DebugMode debugging)
|
||||
public static void addLodToBuffer(long data, long topData, long botData, LodDataView[][] adjData,
|
||||
boolean[] adjFillBlack, byte detailLevel, int offsetPosX, int offsetOosZ, LodQuadBuilder quadBuilder, DebugMode debugging)
|
||||
{
|
||||
short width = (short) (1 << detailLevel);
|
||||
short x = (short) LevelPosUtil.convert(detailLevel, offsetPosX, LodUtil.BLOCK_DETAIL_LEVEL);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.seibel.lod.core.objects;
|
||||
|
||||
import com.seibel.lod.core.util.DataPointUtil;
|
||||
|
||||
public final class LodDataView {
|
||||
private final long[] data;
|
||||
private final int size;
|
||||
private final int offset;
|
||||
public LodDataView(long[] data, int size, int offset) {
|
||||
this.data = data;
|
||||
this.size = size;
|
||||
this.offset = offset;
|
||||
}
|
||||
public long get(int index) {
|
||||
return data[index + offset];
|
||||
}
|
||||
public void set(int index, long value) {
|
||||
data[index + offset] = value;
|
||||
}
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
public void copyTo(long[] target, int offset) {
|
||||
System.arraycopy(data, this.offset, target, offset, size);
|
||||
}
|
||||
public void copyTo(LodDataView target) {
|
||||
System.arraycopy(data, this.offset, target.data, target.offset, size);
|
||||
}
|
||||
|
||||
public boolean mergeWith(LodDataView source, int verticalSize, boolean override) {
|
||||
if (size != source.size) {
|
||||
throw new IllegalArgumentException("Cannot merge views of different sizes");
|
||||
}
|
||||
boolean anyChange = false;
|
||||
for (int o=0; o<(source.size()*verticalSize); o+=verticalSize) {
|
||||
if (override) {
|
||||
if (DataPointUtil.compareDatapointPriority(source.get(o), get(o)) >= 0) {
|
||||
anyChange = true;
|
||||
System.arraycopy(source.data, source.offset+o, data, offset+o, verticalSize);
|
||||
}
|
||||
} else {
|
||||
if (DataPointUtil.compareDatapointPriority(source.get(o), get(o)) > 0) {
|
||||
anyChange = true;
|
||||
System.arraycopy(source.data, source.offset+o, data, offset+o, verticalSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
return anyChange;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
package com.seibel.lod.core.objects.lod;
|
||||
|
||||
import com.seibel.lod.core.objects.LodDataView;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -32,11 +34,11 @@ public interface LevelContainer
|
||||
* @param data actual data to add in an array of long format.
|
||||
* @param posX x position in the detail level
|
||||
* @param posZ z position in the detail level
|
||||
* @param index z position in the detail level
|
||||
* @param index vertical position in the detail level
|
||||
* @return true if correctly added, false otherwise
|
||||
*/
|
||||
boolean addData(long data, int posX, int posZ, int index);
|
||||
|
||||
|
||||
/**
|
||||
* With this you can add data to the level container
|
||||
* @param data actual data to add in an array of long[] format.
|
||||
@@ -44,23 +46,18 @@ public interface LevelContainer
|
||||
* @param posZ z position in the detail level
|
||||
* @return true if correctly changed, false otherwise
|
||||
*/
|
||||
@Deprecated
|
||||
boolean addVerticalData(long[] data, int posX, int posZ, boolean override);
|
||||
boolean copyVerticalData(LodDataView data, int posX, int posZ, boolean override);
|
||||
|
||||
/**
|
||||
* With this you can add a square of data to the level container
|
||||
* @return true if anything changed, false otherwise
|
||||
*/
|
||||
@Deprecated
|
||||
boolean addChunkOfData(long[] data, int posX, int posZ, int widthX, int widthZ, boolean override);
|
||||
|
||||
/**
|
||||
* With this you can add data to the level container
|
||||
* @param data actual data to add in an array of long format.
|
||||
* @param posX x position in the detail level
|
||||
* @param posZ z position in the detail level
|
||||
* @return true if correctly added, false otherwise
|
||||
*/
|
||||
boolean addSingleData(long data, int posX, int posZ);
|
||||
|
||||
boolean copyChunkOfData(LodDataView data, int posX, int posZ, int widthX, int widthZ, boolean override);
|
||||
|
||||
/**
|
||||
* With this you can get data from the level container
|
||||
* @param posX x position in the detail level
|
||||
@@ -75,7 +72,9 @@ public interface LevelContainer
|
||||
* @param posZ z position in the detail level
|
||||
* @return the data in long array format
|
||||
*/
|
||||
@Deprecated
|
||||
long[] getAllData(int posX, int posZ);
|
||||
LodDataView getVerticalDataView(int posX, int posZ);
|
||||
|
||||
/**
|
||||
* With this you can get data from the level container
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.seibel.lod.core.enums.config.DropoffQuality;
|
||||
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.PosToGenerateContainer;
|
||||
import com.seibel.lod.core.objects.PosToRenderContainer;
|
||||
import com.seibel.lod.core.util.DataPointUtil;
|
||||
@@ -205,11 +206,17 @@ public class LodRegion {
|
||||
* @return the data at the relative pos and detail level, 0 if the data doesn't
|
||||
* exist.
|
||||
*/
|
||||
@Deprecated
|
||||
public long[] getAllData(byte detailLevel, int posX, int posZ) {
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
return dataContainer[detailLevel].getAllData(posX, posZ);
|
||||
}
|
||||
public LodDataView getDataView(byte detailLevel, int posX, int posZ) {
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
return dataContainer[detailLevel].getVerticalDataView(posX, posZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dataPoint at the given relative position.
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
||||
import com.seibel.lod.core.objects.LodDataView;
|
||||
import com.seibel.lod.core.util.*;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
|
||||
@@ -37,6 +38,8 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
*/
|
||||
public class VerticalLevelContainer implements LevelContainer
|
||||
{
|
||||
public static final boolean DO_SAFETY_CHECKS = true;
|
||||
|
||||
private final short minHeight;
|
||||
public final byte detailLevel;
|
||||
public final int size;
|
||||
@@ -107,15 +110,36 @@ public class VerticalLevelContainer implements LevelContainer
|
||||
forceWriteVerticalData(data, posX, posZ);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean copyVerticalData(LodDataView data, int posX, int posZ, boolean override) {
|
||||
if (DO_SAFETY_CHECKS) {
|
||||
if (data.size() != verticalSize)
|
||||
throw new IllegalArgumentException("data size not the same as vertical size");
|
||||
if (posX < 0 || posX >= size)
|
||||
throw new IllegalArgumentException("X position is out of bounds");
|
||||
if (posZ < 0 || posZ >= size)
|
||||
throw new IllegalArgumentException("Z position is out of bounds");
|
||||
}
|
||||
int index = posX * size * verticalSize + posZ * verticalSize;
|
||||
int compare = DataPointUtil.compareDatapointPriority(data.get(0), dataContainer[index]);
|
||||
if (override) {
|
||||
if (compare<0) return false;
|
||||
} else {
|
||||
if (compare<=0) return false;
|
||||
}
|
||||
data.copyTo(dataContainer, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addChunkOfData(long[] data, int posX, int posZ, int widthX, int widthZ, boolean override)
|
||||
{
|
||||
boolean anyChange = false;
|
||||
if (posX+widthX > size || posZ+widthZ > size)
|
||||
throw new IndexOutOfBoundsException("addChunkOfData param not inside valid range");
|
||||
if (widthX*widthZ*verticalSize > data.length)
|
||||
throw new IndexOutOfBoundsException("addChunkOfData data array not long enough to contain the data to be copied");
|
||||
if (widthX*widthZ*verticalSize != data.length)
|
||||
throw new IndexOutOfBoundsException("addChunkOfData data array not sized correctly to contain the data to be copied");
|
||||
if (posX<0 || posZ<0 || widthX<0 || widthZ<0)
|
||||
throw new IndexOutOfBoundsException("addChunkOfData param is negative");
|
||||
|
||||
@@ -127,18 +151,31 @@ public class VerticalLevelContainer implements LevelContainer
|
||||
}
|
||||
return anyChange;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean addSingleData(long data, int posX, int posZ)
|
||||
{
|
||||
return addData(data, posX, posZ, 0);
|
||||
public boolean copyChunkOfData(LodDataView data, int posX, int posZ, int widthX, int widthZ, boolean override) {
|
||||
boolean anyChange = false;
|
||||
if (posX+widthX > size || posZ+widthZ > size)
|
||||
throw new IndexOutOfBoundsException("addChunkOfData param not inside valid range");
|
||||
if (widthX*widthZ*verticalSize != data.size())
|
||||
throw new IndexOutOfBoundsException("addChunkOfData data array not sized correctly to contain the data to be copied");
|
||||
if (posX<0 || posZ<0 || widthX<0 || widthZ<0)
|
||||
throw new IndexOutOfBoundsException("addChunkOfData param is negative");
|
||||
|
||||
for (int ox=0; ox<widthX; ox++) {
|
||||
anyChange |= new LodDataView(dataContainer, widthX*verticalSize,
|
||||
((ox+posX)*size+posZ) * verticalSize)
|
||||
.mergeWith(data, verticalSize, override);
|
||||
}
|
||||
return anyChange;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getData(int posX, int posZ, int verticalIndex)
|
||||
{
|
||||
return dataContainer[posX * size * verticalSize + posZ * verticalSize + verticalIndex];
|
||||
}
|
||||
|
||||
|
||||
public short getPositionData(int posX, int posZ)
|
||||
{
|
||||
@@ -194,7 +231,12 @@ public class VerticalLevelContainer implements LevelContainer
|
||||
System.arraycopy(dataContainer, index, result, 0, verticalSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public LodDataView getVerticalDataView(int posX, int posZ) {
|
||||
return new LodDataView(dataContainer, verticalSize, posX * size * verticalSize + posZ * verticalSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVerticalSize()
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.seibel.lod.core.objects.opengl;
|
||||
import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder;
|
||||
import com.seibel.lod.core.enums.LodDirection;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
||||
import com.seibel.lod.core.objects.LodDataView;
|
||||
import com.seibel.lod.core.util.ColorUtil;
|
||||
import com.seibel.lod.core.util.DataPointUtil;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
@@ -31,8 +32,8 @@ public class LodBox
|
||||
private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
|
||||
|
||||
public static void addBoxQuadsToBuilder(LodQuadBuilder builder, short xSize, short ySize, short zSize, short x,
|
||||
short y, short z, int color, byte skyLight, byte blockLight, long topData, long botData, long[][][] adjData,
|
||||
boolean[] adjFillBlack)
|
||||
short y, short z, int color, byte skyLight, byte blockLight, long topData, long botData, LodDataView[][] adjData,
|
||||
boolean[] adjFillBlack)
|
||||
{
|
||||
short maxX = (short) (x + xSize);
|
||||
short maxY = (short) (y + ySize);
|
||||
@@ -57,7 +58,7 @@ public class LodBox
|
||||
|
||||
//NORTH face vertex creation
|
||||
{
|
||||
long[][] adjDataNorth = adjData[LodDirection.NORTH.ordinal() - 2];
|
||||
LodDataView[] adjDataNorth = adjData[LodDirection.NORTH.ordinal() - 2];
|
||||
int adjOverlapNorth = adjFillBlack[LodDirection.NORTH.ordinal() - 2] ? ColorUtil.BLACK : ColorUtil.TRANSPARENT;
|
||||
if (adjDataNorth == null)
|
||||
{
|
||||
@@ -79,7 +80,7 @@ public class LodBox
|
||||
|
||||
//SOUTH face vertex creation
|
||||
{
|
||||
long[][] adjDataSouth = adjData[LodDirection.SOUTH.ordinal() - 2];
|
||||
LodDataView[] adjDataSouth = adjData[LodDirection.SOUTH.ordinal() - 2];
|
||||
int adjOverlapSouth = adjFillBlack[LodDirection.SOUTH.ordinal() - 2] ? ColorUtil.BLACK : ColorUtil.TRANSPARENT;
|
||||
if (adjDataSouth == null)
|
||||
{
|
||||
@@ -102,7 +103,7 @@ public class LodBox
|
||||
|
||||
//WEST face vertex creation
|
||||
{
|
||||
long[][] adjDataWest = adjData[LodDirection.WEST.ordinal() - 2];
|
||||
LodDataView[] adjDataWest = adjData[LodDirection.WEST.ordinal() - 2];
|
||||
int adjOverlapWest = adjFillBlack[LodDirection.WEST.ordinal() - 2] ? ColorUtil.BLACK : ColorUtil.TRANSPARENT;
|
||||
if (adjDataWest == null)
|
||||
{
|
||||
@@ -124,7 +125,7 @@ public class LodBox
|
||||
|
||||
//EAST face vertex creation
|
||||
{
|
||||
long[][] adjDataEast = adjData[LodDirection.EAST.ordinal() - 2];
|
||||
LodDataView[] adjDataEast = adjData[LodDirection.EAST.ordinal() - 2];
|
||||
int adjOverlapEast = adjFillBlack[LodDirection.EAST.ordinal() - 2] ? ColorUtil.BLACK : ColorUtil.TRANSPARENT;
|
||||
if (adjData[LodDirection.EAST.ordinal() - 2] == null)
|
||||
{
|
||||
@@ -145,12 +146,12 @@ public class LodBox
|
||||
}
|
||||
}
|
||||
|
||||
private static void makeAdjQuads(LodQuadBuilder builder, long[] adjData, LodDirection direction, short x, short y,
|
||||
short z, short w0, short wy, int color, int overlapColor, byte upSkyLight, byte blockLight)
|
||||
private static void makeAdjQuads(LodQuadBuilder builder, LodDataView adjData, LodDirection direction, short x, short y,
|
||||
short z, short w0, short wy, int color, int overlapColor, byte upSkyLight, byte blockLight)
|
||||
{
|
||||
color = ColorUtil.applyShade(color, MC.getShade(direction));
|
||||
long[] dataPoint = adjData;
|
||||
if (dataPoint == null || DataPointUtil.isVoid(dataPoint[0]))
|
||||
LodDataView dataPoint = adjData;
|
||||
if (dataPoint == null || DataPointUtil.isVoid(dataPoint.get(0)))
|
||||
{
|
||||
builder.addQuadAdj(direction, x, y, z, w0, wy, color, (byte) 15, blockLight);
|
||||
return;
|
||||
@@ -164,10 +165,10 @@ public class LodBox
|
||||
|
||||
// TODO transparency ocean floor fix
|
||||
// boolean isOpaque = ((colorMap[0] >> 24) & 0xFF) == 255;
|
||||
for (i = 0; i < dataPoint.length && DataPointUtil.doesItExist(adjData[i])
|
||||
&& !DataPointUtil.isVoid(adjData[i]); i++)
|
||||
for (i = 0; i < dataPoint.size() && DataPointUtil.doesItExist(adjData.get(i))
|
||||
&& !DataPointUtil.isVoid(adjData.get(i)); i++)
|
||||
{
|
||||
long adjPoint = adjData[i];
|
||||
long adjPoint = adjData.get(i);
|
||||
|
||||
// TODO transparency ocean floor fix
|
||||
// if (isOpaque && DataPointUtil.getAlpha(singleAdjDataPoint) != 255)
|
||||
@@ -291,8 +292,8 @@ public class LodBox
|
||||
previousDepth = depth;
|
||||
firstFace = false;
|
||||
nextSkyLight = upSkyLight;
|
||||
if (i + 1 < adjData.length && DataPointUtil.doesItExist(adjData[i + 1]))
|
||||
nextSkyLight = DataPointUtil.getLightSky(adjData[i + 1]);
|
||||
if (i + 1 < adjData.size() && DataPointUtil.doesItExist(adjData.get(i + 1)))
|
||||
nextSkyLight = DataPointUtil.getLightSky(adjData.get(i + 1));
|
||||
}
|
||||
|
||||
if (allAbove)
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.seibel.lod.core.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.core.enums.rendering.GLProxyContext;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
||||
import com.seibel.lod.core.objects.BoolType;
|
||||
import com.seibel.lod.core.objects.LodDataView;
|
||||
import com.seibel.lod.core.objects.PosToRenderContainer;
|
||||
import com.seibel.lod.core.objects.lod.LodDimension;
|
||||
import com.seibel.lod.core.objects.lod.LodRegion;
|
||||
@@ -294,13 +295,12 @@ public class RenderRegion implements AutoCloseable
|
||||
// skip any chunks that Minecraft is going to render
|
||||
if (chunkGrid != null && chunkGrid.get(chunkX, chunkZ) != null) continue;
|
||||
}
|
||||
|
||||
long[] posData = region.getAllData(detailLevel, posX, posZ);
|
||||
if (posData == null || posData.length == 0 || !DataPointUtil.doesItExist(posData[0])
|
||||
|| DataPointUtil.isVoid(posData[0]))
|
||||
LodDataView posData = region.getDataView(detailLevel, posX, posZ);
|
||||
if (posData == null || posData.size() == 0 || !DataPointUtil.doesItExist(posData.get(0))
|
||||
|| DataPointUtil.isVoid(posData.get(0)))
|
||||
continue;
|
||||
|
||||
long[][][] adjData = new long[4][][];
|
||||
|
||||
LodDataView[][] adjData = new LodDataView[4][];
|
||||
boolean[] adjUseBlack = new boolean[4];
|
||||
|
||||
// We extract the adj data in the four cardinal direction
|
||||
@@ -360,15 +360,15 @@ public class RenderRegion implements AutoCloseable
|
||||
}
|
||||
|
||||
if (adjDetail == detailLevel || adjDetail > detailLevel) {
|
||||
adjData[lodDirection.ordinal() - 2] = new long[1][];
|
||||
adjData[lodDirection.ordinal() - 2][0] = adjRegion.getAllData(adjDetail,
|
||||
adjData[lodDirection.ordinal() - 2] = new LodDataView[1];
|
||||
adjData[lodDirection.ordinal() - 2][0] = adjRegion.getDataView(adjDetail,
|
||||
LevelPosUtil.convert(detailLevel, xAdj, adjDetail),
|
||||
LevelPosUtil.convert(detailLevel, zAdj, adjDetail));
|
||||
} else {
|
||||
adjData[lodDirection.ordinal() - 2] = new long[2][];
|
||||
adjData[lodDirection.ordinal() - 2][0] = adjRegion.getAllData(adjDetail,
|
||||
adjData[lodDirection.ordinal() - 2] = new LodDataView[2];
|
||||
adjData[lodDirection.ordinal() - 2][0] = adjRegion.getDataView(adjDetail,
|
||||
childXAdj, childZAdj);
|
||||
adjData[lodDirection.ordinal() - 2][1] = adjRegion.getAllData(adjDetail,
|
||||
adjData[lodDirection.ordinal() - 2][1] = adjRegion.getDataView(adjDetail,
|
||||
childXAdj + (lodDirection.getAxis()==LodDirection.Axis.X ? 0 : 1),
|
||||
childZAdj + (lodDirection.getAxis()==LodDirection.Axis.Z ? 0 : 1));
|
||||
}
|
||||
@@ -380,15 +380,15 @@ public class RenderRegion implements AutoCloseable
|
||||
|
||||
// We render every vertical lod present in this position
|
||||
// We only stop when we find a block that is void or non-existing block
|
||||
for (int i = 0; i < posData.length; i++) {
|
||||
long data = posData[i];
|
||||
for (int i = 0; i < posData.size(); i++) {
|
||||
long data = posData.get(i);
|
||||
// If the data is not renderable (Void or non-existing) we stop since there is
|
||||
// no data left in this position
|
||||
if (DataPointUtil.isVoid(data) || !DataPointUtil.doesItExist(data))
|
||||
break;
|
||||
|
||||
long adjDataTop = i - 1 >= 0 ? posData[i - 1] : DataPointUtil.EMPTY_DATA;
|
||||
long adjDataBot = i + 1 < posData.length ? posData[i + 1] : DataPointUtil.EMPTY_DATA;
|
||||
long adjDataTop = i - 1 >= 0 ? posData.get(i - 1) : DataPointUtil.EMPTY_DATA;
|
||||
long adjDataBot = i + 1 < posData.size() ? posData.get(i + 1) : DataPointUtil.EMPTY_DATA;
|
||||
|
||||
// We send the call to create the vertices
|
||||
CubicLodTemplate.addLodToBuffer(data, adjDataTop, adjDataBot, adjData, adjUseBlack, detailLevel,
|
||||
|
||||
Reference in New Issue
Block a user