Reduce memory allocation slightly during LOD loading
This commit is contained in:
+17
-14
@@ -24,7 +24,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.util.objects.pooling.AbstractPhantomArrayList;
|
||||
import com.seibel.distanthorizons.core.util.objects.pooling.PhantomArrayListPool;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnRenderView;
|
||||
import com.seibel.distanthorizons.core.util.RenderDataPointUtil;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
@@ -95,23 +95,24 @@ public class ColumnRenderSource extends AbstractPhantomArrayList
|
||||
|
||||
public long getDataPoint(int posX, int posZ, int verticalIndex) { return this.renderDataContainer.getLong(posX * WIDTH * this.maxVerticalSliceCount + posZ * this.maxVerticalSliceCount + verticalIndex); }
|
||||
|
||||
public ColumnArrayView getVerticalDataPointView(int posX, int posZ)
|
||||
public void populateColumnView(ColumnRenderView view, int posX, int posZ) throws IllegalArgumentException
|
||||
{
|
||||
int offset = posX * WIDTH * this.maxVerticalSliceCount + posZ * this.maxVerticalSliceCount;
|
||||
|
||||
// don't allow returning views that are outside this render source's bounds
|
||||
if (offset >= this.renderDataContainer.size())
|
||||
{
|
||||
return null;
|
||||
throw new IllegalArgumentException("Column View offset ["+offset+"] greater than parent render data container ["+DhSectionPos.toString(this.pos)+"] size ["+this.renderDataContainer.size()+"].");
|
||||
}
|
||||
else if (posX < 0 || posX >= WIDTH
|
||||
|| posZ < 0 || posZ >= WIDTH)
|
||||
{
|
||||
return null;
|
||||
throw new IllegalArgumentException("Column View pos outside valid range ["+posX+","+posZ+"].");
|
||||
}
|
||||
|
||||
return new ColumnArrayView(this.renderDataContainer, this.maxVerticalSliceCount,
|
||||
offset, this.maxVerticalSliceCount);
|
||||
view.populate(
|
||||
this.renderDataContainer, this.maxVerticalSliceCount,
|
||||
offset, this.maxVerticalSliceCount);
|
||||
}
|
||||
|
||||
//endregion
|
||||
@@ -139,18 +140,20 @@ public class ColumnRenderSource extends AbstractPhantomArrayList
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (int x = 0; x < WIDTH; x++)
|
||||
try (ColumnRenderView columnView = ColumnRenderView.getPooled())
|
||||
{
|
||||
for (int z = 0; z < WIDTH; z++)
|
||||
for (int x = 0; x < WIDTH; x++)
|
||||
{
|
||||
ColumnArrayView columnArrayView = this.getVerticalDataPointView(x,z);
|
||||
for (int i = 0; i < columnArrayView.size; i++)
|
||||
for (int z = 0; z < WIDTH; z++)
|
||||
{
|
||||
long dataPoint = columnArrayView.get(i);
|
||||
if (!RenderDataPointUtil.hasZeroHeight(dataPoint))
|
||||
this.populateColumnView(columnView, x, z);
|
||||
for (int i = 0; i < columnView.size; i++)
|
||||
{
|
||||
return true;
|
||||
long dataPoint = columnView.get(i);
|
||||
if (!RenderDataPointUtil.hasZeroHeight(dataPoint))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -27,7 +27,7 @@ import com.seibel.distanthorizons.core.util.objects.pooling.PhantomArrayListChec
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderDataPointUtil;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnRenderView;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
@@ -54,7 +54,7 @@ public class ColumnBox
|
||||
short width, short yHeight,
|
||||
short minX, short minY, short minZ,
|
||||
int color, byte irisBlockMaterialId, byte skyLight, byte blockLight,
|
||||
long topData, long bottomData, ColumnArrayView[] adjData, boolean[] isAdjDataSameDetailLevel)
|
||||
long topData, long bottomData, ColumnRenderView[] adjData, boolean[] isAdjDataSameDetailLevel)
|
||||
{
|
||||
//================//
|
||||
// variable setup //
|
||||
@@ -145,7 +145,7 @@ public class ColumnBox
|
||||
|
||||
// NORTH face
|
||||
{
|
||||
ColumnArrayView adjCol = adjData[EDhDirection.NORTH.compassIndex];
|
||||
ColumnRenderView adjCol = adjData[EDhDirection.NORTH.compassIndex];
|
||||
boolean adjSameDetailLevel = isAdjDataSameDetailLevel[EDhDirection.NORTH.compassIndex];
|
||||
// if the adjacent column is null that generally means the adjacent area hasn't been generated yet
|
||||
if (adjCol == null)
|
||||
@@ -172,7 +172,7 @@ public class ColumnBox
|
||||
|
||||
// SOUTH face
|
||||
{
|
||||
ColumnArrayView adjCol = adjData[EDhDirection.SOUTH.compassIndex];
|
||||
ColumnRenderView adjCol = adjData[EDhDirection.SOUTH.compassIndex];
|
||||
boolean adjSameDetailLevel = isAdjDataSameDetailLevel[EDhDirection.SOUTH.compassIndex];
|
||||
if (adjCol == null)
|
||||
{
|
||||
@@ -197,7 +197,7 @@ public class ColumnBox
|
||||
|
||||
// WEST face
|
||||
{
|
||||
ColumnArrayView adjCol = adjData[EDhDirection.WEST.compassIndex];
|
||||
ColumnRenderView adjCol = adjData[EDhDirection.WEST.compassIndex];
|
||||
boolean adjSameDetailLevel = isAdjDataSameDetailLevel[EDhDirection.WEST.compassIndex];
|
||||
if (adjCol == null)
|
||||
{
|
||||
@@ -222,7 +222,7 @@ public class ColumnBox
|
||||
|
||||
// EAST face
|
||||
{
|
||||
ColumnArrayView adjCol = adjData[EDhDirection.EAST.compassIndex];
|
||||
ColumnRenderView adjCol = adjData[EDhDirection.EAST.compassIndex];
|
||||
boolean adjSameDetailLevel = isAdjDataSameDetailLevel[EDhDirection.EAST.compassIndex];
|
||||
if (adjCol == null)
|
||||
{
|
||||
@@ -248,7 +248,7 @@ public class ColumnBox
|
||||
|
||||
private static void makeAdjVerticalQuad(
|
||||
LodQuadBuilder builder, PhantomArrayListCheckout phantomArrayCheckout,
|
||||
@NotNull ColumnArrayView adjColumnView, boolean adjacentIsSameDetailLevel, int caveCullingMaxY, EDhDirection direction,
|
||||
@NotNull ColumnRenderView adjColumnView, boolean adjacentIsSameDetailLevel, int caveCullingMaxY, EDhDirection direction,
|
||||
short x, short yMin, short z, short horizontalWidth, short ySize,
|
||||
int color, byte irisBlockMaterialId, byte blockLight)
|
||||
{
|
||||
|
||||
+29
-20
@@ -34,7 +34,7 @@ import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderDataPointUtil;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnRenderView;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -107,17 +107,29 @@ public class ColumnRenderBufferBuilder
|
||||
//===================//
|
||||
|
||||
// pooled arrays for ColumnBox use
|
||||
try (PhantomArrayListCheckout phantomArrayCheckout = ARRAY_LIST_POOL.checkoutLongArrays(2))
|
||||
try (PhantomArrayListCheckout phantomArrayCheckout = ARRAY_LIST_POOL.checkoutLongArrays(2);
|
||||
ColumnRenderView columnRenderData = ColumnRenderView.getPooled();
|
||||
ColumnRenderView northAdjView = ColumnRenderView.getPooled();
|
||||
ColumnRenderView southAdjView = ColumnRenderView.getPooled();
|
||||
ColumnRenderView eastAdjView = ColumnRenderView.getPooled();
|
||||
ColumnRenderView westAdjView = ColumnRenderView.getPooled())
|
||||
{
|
||||
ColumnRenderView[] adjColumnViews = new ColumnRenderView[EDhDirection.CARDINAL_COMPASS.length];
|
||||
adjColumnViews[EDhDirection.NORTH.compassIndex] = northAdjView;
|
||||
adjColumnViews[EDhDirection.SOUTH.compassIndex] = southAdjView;
|
||||
adjColumnViews[EDhDirection.EAST.compassIndex] = eastAdjView;
|
||||
adjColumnViews[EDhDirection.WEST.compassIndex] = westAdjView;
|
||||
|
||||
|
||||
byte thisDetailLevel = renderSource.getDataDetailLevel();
|
||||
for (int relX = 0; relX < ColumnRenderSource.WIDTH; relX++)
|
||||
{
|
||||
for (int relZ = 0; relZ < ColumnRenderSource.WIDTH; relZ++)
|
||||
{
|
||||
// ignore empty/null columns
|
||||
ColumnArrayView columnRenderData = renderSource.getVerticalDataPointView(relX, relZ);
|
||||
if (columnRenderData == null
|
||||
|| columnRenderData.size == 0
|
||||
renderSource.populateColumnView(columnRenderData, relX, relZ);
|
||||
|
||||
// ignore empty columns
|
||||
if (columnRenderData.size == 0
|
||||
|| !RenderDataPointUtil.doesDataPointExist(columnRenderData.get(0))
|
||||
|| RenderDataPointUtil.hasZeroHeight(columnRenderData.get(0)))
|
||||
{
|
||||
@@ -125,7 +137,6 @@ public class ColumnRenderBufferBuilder
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// debug limit //
|
||||
//=============//
|
||||
@@ -152,7 +163,6 @@ public class ColumnRenderBufferBuilder
|
||||
// get adjacent render data columns //
|
||||
//==================================//
|
||||
|
||||
ColumnArrayView[] adjColumnViews = new ColumnArrayView[EDhDirection.CARDINAL_COMPASS.length];
|
||||
for (EDhDirection direction : EDhDirection.CARDINAL_COMPASS)
|
||||
{
|
||||
try
|
||||
@@ -160,8 +170,8 @@ public class ColumnRenderBufferBuilder
|
||||
int xAdj = relX + direction.normal.x;
|
||||
int zAdj = relZ + direction.normal.z;
|
||||
boolean isCrossRenderSourceBoundary =
|
||||
(xAdj < 0 || xAdj >= ColumnRenderSource.WIDTH) ||
|
||||
(zAdj < 0 || zAdj >= ColumnRenderSource.WIDTH);
|
||||
(xAdj < 0 || xAdj >= ColumnRenderSource.WIDTH)
|
||||
|| (zAdj < 0 || zAdj >= ColumnRenderSource.WIDTH);
|
||||
|
||||
ColumnRenderSource adjRenderSource;
|
||||
byte adjDetailLevel;
|
||||
@@ -230,7 +240,7 @@ public class ColumnRenderBufferBuilder
|
||||
LodUtil.assertNotReach("Mismatch between adjacent detail level ["+adjDetailLevel+"] and this render source's detail level ["+thisDetailLevel+"]. Detail levels should be adj >= this.");
|
||||
}
|
||||
|
||||
adjColumnViews[direction.compassIndex] = adjRenderSource.getVerticalDataPointView(xAdj, zAdj);
|
||||
adjRenderSource.populateColumnView(adjColumnViews[direction.compassIndex], xAdj, zAdj);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
@@ -251,7 +261,7 @@ public class ColumnRenderBufferBuilder
|
||||
{
|
||||
int wantedColumnIndex = Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugColumnIndex.get();
|
||||
if (wantedColumnIndex >= 0
|
||||
&& i != wantedColumnIndex)
|
||||
&& i != wantedColumnIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -261,7 +271,7 @@ public class ColumnRenderBufferBuilder
|
||||
// If the data is not render-able (Void or non-existing) we stop since there is
|
||||
// no data left in this position
|
||||
if (RenderDataPointUtil.hasZeroHeight(data)
|
||||
|| !RenderDataPointUtil.doesDataPointExist(data))
|
||||
|| !RenderDataPointUtil.doesDataPointExist(data))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -270,13 +280,12 @@ public class ColumnRenderBufferBuilder
|
||||
long bottomDataPoint = (i + 1) < columnRenderData.size ? columnRenderData.get(i + 1) : RenderDataPointUtil.EMPTY_DATA;
|
||||
|
||||
addRenderDataPointToBuilder(
|
||||
clientLevel, phantomArrayCheckout,
|
||||
data, topDataPoint, bottomDataPoint,
|
||||
adjColumnViews, isSameDetailLevel,
|
||||
thisDetailLevel, relX, relZ,
|
||||
quadBuilder);
|
||||
clientLevel, phantomArrayCheckout,
|
||||
data, topDataPoint, bottomDataPoint,
|
||||
adjColumnViews, isSameDetailLevel,
|
||||
thisDetailLevel, relX, relZ,
|
||||
quadBuilder);
|
||||
}
|
||||
|
||||
}// for z
|
||||
}// for x
|
||||
}// phantom checkout
|
||||
@@ -286,7 +295,7 @@ public class ColumnRenderBufferBuilder
|
||||
private static void addRenderDataPointToBuilder(
|
||||
IDhClientLevel clientLevel, PhantomArrayListCheckout phantomArrayCheckout,
|
||||
long renderData, long topRenderData, long bottomRenderData,
|
||||
ColumnArrayView[] adjColumnViews, boolean[] isSameDetailLevel,
|
||||
ColumnRenderView[] adjColumnViews, boolean[] isSameDetailLevel,
|
||||
byte detailLevel, int renderSourceOffsetPosX, int renderSourceOffsetPosZ,
|
||||
LodQuadBuilder quadBuilder)
|
||||
{
|
||||
|
||||
+121
-45
@@ -28,28 +28,37 @@ import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public final class ColumnArrayView
|
||||
/**
|
||||
* Maps to part of a {@link ColumnRenderSource} for easier handling.
|
||||
*
|
||||
* @see ColumnRenderSource
|
||||
*/
|
||||
public final class ColumnRenderView implements AutoCloseable
|
||||
{
|
||||
public final LongArrayList data;
|
||||
private static final ConcurrentLinkedQueue<ColumnRenderView> POOL = new ConcurrentLinkedQueue<>();
|
||||
|
||||
|
||||
public LongArrayList data;
|
||||
|
||||
/**
|
||||
* How many data points are currently being represented by this view. <br>
|
||||
* Will be equal to or less than {@link ColumnArrayView#maxVerticalSliceCount}.
|
||||
* Will be equal to or less than {@link ColumnRenderView#maxVerticalSliceCount}.
|
||||
*/
|
||||
public final int size;
|
||||
public int size;
|
||||
/**
|
||||
* Vertical size in data points. <Br>
|
||||
* Can be 0 if this column was created for an empty data source.
|
||||
* @see EDhApiVerticalQuality#calculateMaxNumberOfVerticalSlicesAtDetailLevel(byte)
|
||||
*/
|
||||
public final int maxVerticalSliceCount;
|
||||
public int maxVerticalSliceCount;
|
||||
|
||||
/**
|
||||
* Where the relative starting index is in the {@link ColumnArrayView#data} array
|
||||
* Where the relative starting index is in the {@link ColumnRenderView#data} array
|
||||
* if this view is representing part of a {@link ColumnRenderSource}.
|
||||
*/
|
||||
public final int offset;
|
||||
public int offset;
|
||||
|
||||
|
||||
|
||||
@@ -58,8 +67,38 @@ public final class ColumnArrayView
|
||||
//=============//
|
||||
//region
|
||||
|
||||
/** @throws IllegalArgumentException if the offset is greater than the data's size */
|
||||
public ColumnArrayView(LongArrayList data, int size, int offset, int maxVerticalSliceCount) throws IllegalArgumentException
|
||||
private ColumnRenderView() { }
|
||||
|
||||
/**
|
||||
* returns an un-populated view. <br>
|
||||
* {@link ColumnRenderView#populate(LongArrayList, int, int, int)} must be called before the
|
||||
* view can be used.s
|
||||
*/
|
||||
public static ColumnRenderView getPooled() { return getPooled(null, 0, 0, 0); }
|
||||
public static ColumnRenderView getPooled(LongArrayList data, int size, int offset, int maxVerticalSliceCount) throws IllegalArgumentException
|
||||
{
|
||||
// try getting an existing pooled object first
|
||||
ColumnRenderView view = POOL.poll();
|
||||
if (view == null)
|
||||
{
|
||||
// no pooled object
|
||||
view = new ColumnRenderView();
|
||||
}
|
||||
|
||||
// data will be null if the object will be populated at a later date
|
||||
if (data != null)
|
||||
{
|
||||
view.populate(data, size, offset, maxVerticalSliceCount);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutates this object so the necessary data is visible.
|
||||
* @throws IllegalArgumentException if the offset is greater than the data's size
|
||||
*/
|
||||
public void populate(LongArrayList data, int size, int offset, int maxVerticalSliceCount) throws IllegalArgumentException
|
||||
{
|
||||
this.data = data;
|
||||
this.size = size;
|
||||
@@ -97,16 +136,63 @@ public final class ColumnArrayView
|
||||
}
|
||||
public void set(int index, long value) { this.data.set(index + this.offset, value); }
|
||||
|
||||
public void fill(long value) { Arrays.fill(this.data.elements(), this.offset, this.offset + this.size, value); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
//=========//
|
||||
// subview //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
/** should be called in a try-finally block for automatic cleanup */
|
||||
public ColumnRenderView subView(int dataIndexStart, int dataCount)
|
||||
{
|
||||
return ColumnRenderView.getPooled(
|
||||
this.data,
|
||||
dataCount * this.maxVerticalSliceCount,
|
||||
this.offset + dataIndexStart * this.maxVerticalSliceCount,
|
||||
this.maxVerticalSliceCount);
|
||||
}
|
||||
|
||||
|
||||
/** can be used to determine sub-view starting indexes */
|
||||
public int subViewCount() { return (this.maxVerticalSliceCount != 0) ? (this.size / this.maxVerticalSliceCount) : 0; }
|
||||
|
||||
public ColumnArrayView subView(int dataIndexStart, int dataCount)
|
||||
{ return new ColumnArrayView(this.data, dataCount * this.maxVerticalSliceCount, this.offset + dataIndexStart * this.maxVerticalSliceCount, this.maxVerticalSliceCount); }
|
||||
//endregion
|
||||
|
||||
public void fill(long value) { Arrays.fill(this.data.elements(), this.offset, this.offset + this.size, value); }
|
||||
|
||||
public void copyFrom(ColumnArrayView source) { this.copyFrom(source, 0); }
|
||||
public void copyFrom(ColumnArrayView source, int outputDataIndexOffset)
|
||||
|
||||
//======================//
|
||||
// change vertical size //
|
||||
//======================//
|
||||
//region
|
||||
|
||||
public void changeVerticalSizeFrom(ColumnRenderView source, RenderDataPointReducingList reducingList)
|
||||
{
|
||||
if (this.subViewCount() != source.subViewCount())
|
||||
{
|
||||
throw new IllegalArgumentException("Cannot copy and resize to views with different dataCounts");
|
||||
}
|
||||
|
||||
if (this.maxVerticalSliceCount >= source.maxVerticalSliceCount)
|
||||
{
|
||||
this.copyFrom(source, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < this.subViewCount(); i++)
|
||||
{
|
||||
try(ColumnRenderView sourceSubView = source.subView(i, 1);
|
||||
ColumnRenderView thisSubView = this.subView(i, 1))
|
||||
{
|
||||
mergeMultiData(sourceSubView, reducingList, thisSubView);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void copyFrom(ColumnRenderView source, int outputDataIndexOffset)
|
||||
{
|
||||
if (source.maxVerticalSliceCount > this.maxVerticalSliceCount)
|
||||
{
|
||||
@@ -121,9 +207,14 @@ public final class ColumnArrayView
|
||||
for (int i = 0; i < source.subViewCount(); i++)
|
||||
{
|
||||
int outputOffset = this.offset + (outputDataIndexOffset * this.maxVerticalSliceCount) + (i * this.maxVerticalSliceCount);
|
||||
source.subView(i, 1).copyTo(this.data.elements(), outputOffset, source.maxVerticalSliceCount);
|
||||
Arrays.fill(this.data.elements(), outputOffset + source.maxVerticalSliceCount,
|
||||
outputOffset + this.maxVerticalSliceCount, 0);
|
||||
try(ColumnRenderView subView = source.subView(i, 1))
|
||||
{
|
||||
subView.copyTo(this.data.elements(), outputOffset, source.maxVerticalSliceCount);
|
||||
Arrays.fill(this.data.elements(),
|
||||
outputOffset + source.maxVerticalSliceCount,
|
||||
outputOffset + this.maxVerticalSliceCount,
|
||||
0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -131,35 +222,14 @@ public final class ColumnArrayView
|
||||
source.copyTo(this.data.elements(), this.offset + outputDataIndexOffset * this.maxVerticalSliceCount, source.size);
|
||||
}
|
||||
}
|
||||
|
||||
public void copyTo(long[] target, int offset, int size) { System.arraycopy(this.data.elements(), this.offset, target, offset, size); }
|
||||
|
||||
public void changeVerticalSizeFrom(ColumnArrayView source)
|
||||
{
|
||||
if (this.subViewCount() != source.subViewCount())
|
||||
{
|
||||
throw new IllegalArgumentException("Cannot copy and resize to views with different dataCounts");
|
||||
}
|
||||
|
||||
if (this.maxVerticalSliceCount >= source.maxVerticalSliceCount)
|
||||
{
|
||||
this.copyFrom(source);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < this.subViewCount(); i++)
|
||||
{
|
||||
mergeMultiData(source.subView(i, 1), this.subView(i, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
private void copyTo(long[] target, int offset, int size) { System.arraycopy(this.data.elements(), this.offset, target, offset, size); }
|
||||
/**
|
||||
* This method merge column of multiple data together
|
||||
*
|
||||
* @param sourceData one or more columns of data
|
||||
* @param output one column of space for the result to be written to
|
||||
*/
|
||||
private static void mergeMultiData(ColumnArrayView sourceData, ColumnArrayView output)
|
||||
private static void mergeMultiData(ColumnRenderView sourceData, RenderDataPointReducingList reducingList, ColumnRenderView output)
|
||||
{
|
||||
int target = output.maxVerticalSliceCount;
|
||||
if (target <= 0)
|
||||
@@ -179,11 +249,9 @@ public final class ColumnArrayView
|
||||
}
|
||||
else
|
||||
{
|
||||
try (RenderDataPointReducingList list = new RenderDataPointReducingList(sourceData))
|
||||
{
|
||||
list.reduce(output.maxVerticalSliceCount);
|
||||
list.copyTo(output);
|
||||
}
|
||||
reducingList.populate(sourceData);
|
||||
reducingList.reduce(output.maxVerticalSliceCount);
|
||||
reducingList.copyTo(output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +286,14 @@ public final class ColumnArrayView
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
// no validation is done to make sure this object is only added to the pool once
|
||||
// please only use this object in a try-finally so the close is handled implicitly
|
||||
POOL.add(this);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
+36
-28
@@ -24,13 +24,13 @@ import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderSource;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnRenderView;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
|
||||
import com.seibel.distanthorizons.core.util.objects.pooling.PhantomArrayListCheckout;
|
||||
import com.seibel.distanthorizons.core.util.objects.pooling.PhantomArrayListPool;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
|
||||
import com.seibel.distanthorizons.core.util.*;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
@@ -40,6 +40,7 @@ import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -122,30 +123,40 @@ public class FullDataToRenderDataTransformer
|
||||
int baseX = DhSectionPos.getMinCornerBlockX(pos);
|
||||
int baseZ = DhSectionPos.getMinCornerBlockZ(pos);
|
||||
|
||||
for (int x = 0; x < FullDataSourceV2.WIDTH; x++)
|
||||
try(ColumnRenderView columnArrayView = ColumnRenderView.getPooled();
|
||||
PhantomArrayListCheckout phantomCheckout = ARRAY_LIST_POOL.checkoutLongArrays(1);
|
||||
ColumnRenderView tempExpandingColumnView = ColumnRenderView.getPooled();
|
||||
RenderDataPointReducingList reducingList = new RenderDataPointReducingList())
|
||||
{
|
||||
for (int z = 0; z < FullDataSourceV2.WIDTH; z++)
|
||||
for (int x = 0; x < FullDataSourceV2.WIDTH; x++)
|
||||
{
|
||||
ColumnArrayView columnArrayView = columnSource.getVerticalDataPointView(x, z);
|
||||
LongArrayList dataColumn = fullDataSource.getColumnAtRelPos(x, z);
|
||||
|
||||
updateOrReplaceRenderDataViewColumnWithFullDataColumn(
|
||||
levelWrapper, fullDataSource,
|
||||
// bitshift is to account for LODs with a detail level greater than 0 so the block pos is correct
|
||||
baseX + BitShiftUtil.pow(x,dataDetail), baseZ + BitShiftUtil.pow(z,dataDetail),
|
||||
columnArrayView, dataColumn);
|
||||
for (int z = 0; z < FullDataSourceV2.WIDTH; z++)
|
||||
{
|
||||
columnSource.populateColumnView(columnArrayView, x, z);
|
||||
LongArrayList dataColumn = fullDataSource.getColumnAtRelPos(x, z);
|
||||
|
||||
updateOrReplaceRenderDataViewColumnWithFullDataColumn(
|
||||
levelWrapper, fullDataSource,
|
||||
// bit shift is to account for LODs with a detail level greater than 0 so the block pos is correct
|
||||
baseX + BitShiftUtil.pow(x, dataDetail), baseZ + BitShiftUtil.pow(z, dataDetail),
|
||||
columnArrayView, dataColumn,
|
||||
// pooled references so we don't need to re-allocate/get them 4000 times per render source
|
||||
phantomCheckout, tempExpandingColumnView, reducingList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return columnSource;
|
||||
}
|
||||
|
||||
/** Updates the given {@link ColumnArrayView} to match the incoming Full data {@link LongArrayList} */
|
||||
/** Updates the given {@link ColumnRenderView} to match the incoming Full data {@link LongArrayList} */
|
||||
public static void updateOrReplaceRenderDataViewColumnWithFullDataColumn(
|
||||
IClientLevelWrapper levelWrapper,
|
||||
FullDataSourceV2 fullDataSource, int blockX, int blockZ,
|
||||
ColumnArrayView columnArrayView,
|
||||
LongArrayList fullDataColumn)
|
||||
ColumnRenderView columnArrayView,
|
||||
LongArrayList fullDataColumn,
|
||||
// pooled references
|
||||
PhantomArrayListCheckout phantomCheckout, ColumnRenderView tempExpandingColumnView, RenderDataPointReducingList reducingList)
|
||||
{
|
||||
// we can't do anything if the full data is missing or empty
|
||||
if (fullDataColumn == null
|
||||
@@ -162,22 +173,19 @@ public class FullDataToRenderDataTransformer
|
||||
}
|
||||
else
|
||||
{
|
||||
try(PhantomArrayListCheckout checkout = ARRAY_LIST_POOL.checkoutLongArrays(1))
|
||||
{
|
||||
LongArrayList dataArrayList = checkout.getLongArray(0, fullDataLength);
|
||||
|
||||
// expand the ColumnArrayView to fit the new larger max vertical size
|
||||
ColumnArrayView newColumnArrayView = new ColumnArrayView(dataArrayList, fullDataLength, 0, fullDataLength);
|
||||
setRenderColumnView(levelWrapper, fullDataSource, blockX, blockZ, newColumnArrayView, fullDataColumn);
|
||||
|
||||
columnArrayView.changeVerticalSizeFrom(newColumnArrayView);
|
||||
}
|
||||
LongArrayList dataArrayList = phantomCheckout.getLongArray(0, fullDataLength);
|
||||
|
||||
// expand the ColumnArrayView to fit the new larger max vertical size
|
||||
tempExpandingColumnView.populate(dataArrayList, fullDataLength, 0, fullDataLength);
|
||||
setRenderColumnView(levelWrapper, fullDataSource, blockX, blockZ, tempExpandingColumnView, fullDataColumn);
|
||||
|
||||
columnArrayView.changeVerticalSizeFrom(tempExpandingColumnView, reducingList);
|
||||
}
|
||||
}
|
||||
private static void setRenderColumnView(
|
||||
IClientLevelWrapper levelWrapper, FullDataSourceV2 fullDataSource,
|
||||
int blockX, int blockZ,
|
||||
ColumnArrayView renderColumnData, LongArrayList fullColumnData)
|
||||
ColumnRenderView renderColumnData, LongArrayList fullColumnData)
|
||||
{
|
||||
//===============//
|
||||
// config values //
|
||||
@@ -186,8 +194,8 @@ public class FullDataToRenderDataTransformer
|
||||
boolean ignoreNonCollidingBlocks = (Config.Client.Advanced.Graphics.Quality.blocksToIgnore.get() == EDhApiBlocksToAvoid.NON_COLLIDING);
|
||||
boolean colorBelowWithAvoidedBlocks = Config.Client.Advanced.Graphics.Quality.tintWithAvoidedBlocks.get();
|
||||
|
||||
HashSet<IBlockStateWrapper> blockStatesToIgnore = WRAPPER_FACTORY.getRendererIgnoredBlocks(levelWrapper);
|
||||
HashSet<IBlockStateWrapper> caveBlockStatesToIgnore = WRAPPER_FACTORY.getRendererIgnoredCaveBlocks(levelWrapper);
|
||||
ObjectOpenHashSet<IBlockStateWrapper> blockStatesToIgnore = WRAPPER_FACTORY.getRendererIgnoredBlocks(levelWrapper);
|
||||
ObjectOpenHashSet<IBlockStateWrapper> caveBlockStatesToIgnore = WRAPPER_FACTORY.getRendererIgnoredCaveBlocks(levelWrapper);
|
||||
|
||||
// build snow block cache if needed
|
||||
if (snowLayerBlockStates == null)
|
||||
|
||||
+15
-7
@@ -20,7 +20,7 @@
|
||||
package com.seibel.distanthorizons.core.util;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnRenderView;
|
||||
import com.seibel.distanthorizons.core.util.objects.pooling.AbstractPhantomArrayList;
|
||||
import com.seibel.distanthorizons.core.util.objects.pooling.PhantomArrayListPool;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil.AssertFailureException;
|
||||
@@ -103,7 +103,7 @@ public class RenderDataPointReducingList extends AbstractPhantomArrayList
|
||||
*/
|
||||
private short lowest, highest, smallest, biggest;
|
||||
private short sizeWithAir, sizeWithoutAir;
|
||||
private final LongArrayList links, data;
|
||||
private LongArrayList links, data;
|
||||
/**
|
||||
* a temporary array to be used for sorting nodes.
|
||||
* the array is first populated such that every index
|
||||
@@ -112,7 +112,7 @@ public class RenderDataPointReducingList extends AbstractPhantomArrayList
|
||||
* finally, the nodes are re-linked according
|
||||
* to the order of elements in this array.
|
||||
*/
|
||||
private final ShortArrayList sortingArray;
|
||||
private ShortArrayList sortingArray;
|
||||
|
||||
|
||||
|
||||
@@ -120,10 +120,18 @@ public class RenderDataPointReducingList extends AbstractPhantomArrayList
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public RenderDataPointReducingList(ColumnArrayView view)
|
||||
public RenderDataPointReducingList()
|
||||
{
|
||||
super(ARRAY_LIST_POOL, 0, 1, 2, 0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutates this object so it can be used for the given {@link ColumnRenderView}. <Br>
|
||||
* Note: this must be called before this list can be used and this
|
||||
* object can only be used by one thread at a time.
|
||||
*/
|
||||
public void populate(ColumnRenderView view)
|
||||
{
|
||||
int size = view.size;
|
||||
if (size == 0)
|
||||
{
|
||||
@@ -833,7 +841,7 @@ public class RenderDataPointReducingList extends AbstractPhantomArrayList
|
||||
*
|
||||
* @implNote this method does not allocate any objects.
|
||||
*/
|
||||
public static long reduceToOne(ColumnArrayView view)
|
||||
public static long reduceToOne(ColumnRenderView view)
|
||||
{
|
||||
int size = view.size;
|
||||
if (size <= 0)
|
||||
@@ -880,7 +888,7 @@ public class RenderDataPointReducingList extends AbstractPhantomArrayList
|
||||
|
||||
|
||||
/** transfers the contents of this list to the provided view, in order of highest to lowest. */
|
||||
public void copyTo(ColumnArrayView view)
|
||||
public void copyTo(ColumnRenderView view)
|
||||
{
|
||||
// reminder: DH explodes horribly when I copy the nodes
|
||||
// from lowest to highest instead of highest to lowest.
|
||||
|
||||
+3
-2
@@ -27,6 +27,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.IBatchGeneratorEnvironmentWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
@@ -81,12 +82,12 @@ public interface IWrapperFactory extends IDhApiWrapperFactory, IBindable
|
||||
* Returns the set of {@link IBlockStateWrapper}'s that shouldn't be rendered. <br>
|
||||
* Generally this contains blocks like: air, barriers, light blocks, etc.
|
||||
*/
|
||||
HashSet<IBlockStateWrapper> getRendererIgnoredBlocks(ILevelWrapper levelWrapper);
|
||||
ObjectOpenHashSet<IBlockStateWrapper> getRendererIgnoredBlocks(ILevelWrapper levelWrapper);
|
||||
/**
|
||||
* Returns the set of {@link IBlockStateWrapper}'s that shouldn't be rendered in caves. <br>
|
||||
* Generally this contains blocks like: air, rails, glow lichen, etc.
|
||||
*/
|
||||
HashSet<IBlockStateWrapper> getRendererIgnoredCaveBlocks(ILevelWrapper levelWrapper);
|
||||
ObjectOpenHashSet<IBlockStateWrapper> getRendererIgnoredCaveBlocks(ILevelWrapper levelWrapper);
|
||||
|
||||
/** clears the cached values */
|
||||
void resetRendererIgnoredCaveBlocks();
|
||||
|
||||
Reference in New Issue
Block a user