First fix on light & impl render source direct write
This commit is contained in:
@@ -2,14 +2,10 @@ package com.seibel.lod.core.a7.datatype;
|
||||
|
||||
import com.seibel.lod.core.a7.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.a7.level.IClientLevel;
|
||||
import com.seibel.lod.core.a7.level.ILevel;
|
||||
import com.seibel.lod.core.a7.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.a7.render.LodQuadTree;
|
||||
import com.seibel.lod.core.a7.render.RenderBuffer;
|
||||
import com.seibel.lod.core.a7.save.io.file.DataMetaFile;
|
||||
import com.seibel.lod.core.a7.save.io.render.RenderMetaFile;
|
||||
import com.seibel.lod.core.objects.DHChunkPos;
|
||||
import com.seibel.lod.core.objects.DHRegionPos;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
@@ -24,6 +20,7 @@ public interface LodRenderSource {
|
||||
void dispose(); // notify the container that the parent lodSection is now disposed (can be in loaded or unloaded state)
|
||||
byte getDetailOffset();
|
||||
|
||||
|
||||
/**
|
||||
* Try and swap in new render buffer for this section. Note that before this call, there should be no other
|
||||
* places storing or referencing the render buffer.
|
||||
@@ -34,12 +31,11 @@ public interface LodRenderSource {
|
||||
|
||||
void saveRender(IClientLevel level, RenderMetaFile file, OutputStream dataStream) throws IOException;
|
||||
|
||||
void update(ChunkSizedData chunkData);
|
||||
void write(ChunkSizedData chunkData);
|
||||
void flushWrites(IClientLevel level);
|
||||
|
||||
byte getRenderVersion();
|
||||
|
||||
void markInvalid();
|
||||
|
||||
/**
|
||||
* Whether this object is still valid. If not, a new one should be created.
|
||||
*/
|
||||
|
||||
@@ -49,14 +49,16 @@ public class PlaceHolderRenderSource implements LodRenderSource {
|
||||
throw new UnsupportedOperationException("EmptyRenderSource should NEVER be saved!");
|
||||
}
|
||||
@Override
|
||||
public void update(ChunkSizedData chunkData) {}
|
||||
public void write(ChunkSizedData chunkData) {}
|
||||
|
||||
@Override
|
||||
public void flushWrites(IClientLevel level) {}
|
||||
|
||||
@Override
|
||||
public byte getRenderVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markInvalid() {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.seibel.lod.core.a7.datatype.column.accessor.ColumnQuadView;
|
||||
import com.seibel.lod.core.a7.datatype.column.accessor.IColumnDatatype;
|
||||
import com.seibel.lod.core.a7.datatype.column.render.ColumnRenderBuffer;
|
||||
import com.seibel.lod.core.a7.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.a7.datatype.transform.FullToColumnTransformer;
|
||||
import com.seibel.lod.core.a7.level.IClientLevel;
|
||||
import com.seibel.lod.core.a7.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.a7.render.RenderBuffer;
|
||||
@@ -26,6 +27,7 @@ import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
@@ -321,17 +323,27 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
|
||||
@Override
|
||||
public void saveRender(IClientLevel level, RenderMetaFile file, OutputStream dataStream) throws IOException {
|
||||
flushWrites(level);
|
||||
try (DataOutputStream dos = new DataOutputStream(dataStream)) {
|
||||
writeData(dos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(ChunkSizedData chunkData) {
|
||||
//TODO Update render data directly
|
||||
private final ConcurrentLinkedQueue<ChunkSizedData> writeRequest = new ConcurrentLinkedQueue<>();
|
||||
|
||||
//TEMP DEUBG
|
||||
isValid = false;
|
||||
@Override
|
||||
public void write(ChunkSizedData chunkData) {
|
||||
writeRequest.add(chunkData);
|
||||
}
|
||||
@Override
|
||||
public void flushWrites(IClientLevel level) {
|
||||
boolean didSomething = false;
|
||||
while (!writeRequest.isEmpty()) {
|
||||
ChunkSizedData chunkData = writeRequest.poll();
|
||||
FullToColumnTransformer.writeFullDataChunkToColumnData(this, level, chunkData);
|
||||
didSomething = true;
|
||||
}
|
||||
if (didSomething) lastNs = -1; // Reset the timeout to allow rebuilding the buffer again
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -339,14 +351,8 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
return LATEST_VERSION;
|
||||
}
|
||||
|
||||
private boolean isValid = true;
|
||||
@Override
|
||||
public void markInvalid() {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return isValid;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+53
-2
@@ -3,6 +3,8 @@ package com.seibel.lod.core.a7.datatype.transform;
|
||||
import com.seibel.lod.core.a7.datatype.column.accessor.ColumnFormat;
|
||||
import com.seibel.lod.core.a7.datatype.column.ColumnRenderSource;
|
||||
import com.seibel.lod.core.a7.datatype.column.accessor.ColumnArrayView;
|
||||
import com.seibel.lod.core.a7.datatype.column.accessor.ColumnQuadView;
|
||||
import com.seibel.lod.core.a7.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.a7.datatype.full.FullDataSource;
|
||||
import com.seibel.lod.core.a7.datatype.full.FullFormat;
|
||||
import com.seibel.lod.core.a7.datatype.full.IdBiomeBlockStateMap;
|
||||
@@ -60,11 +62,60 @@ public class FullToColumnTransformer {
|
||||
throw new UnsupportedOperationException("To be implemented");
|
||||
//FIXME: Implement different size creation of renderData
|
||||
}
|
||||
|
||||
|
||||
return columnSource;
|
||||
}
|
||||
|
||||
public static void writeFullDataChunkToColumnData(ColumnRenderSource render, IClientLevel level, ChunkSizedData data) {
|
||||
if (data.dataDetail != 0)
|
||||
throw new UnsupportedOperationException("To be implemented");
|
||||
|
||||
final DhSectionPos pos = render.getSectionPos();
|
||||
final int renderOffsetX = (data.x*16) - pos.getCorner().getCorner().x;
|
||||
final int renderOffsetZ = (data.z*16) - pos.getCorner().getCorner().z;
|
||||
final int blockX = pos.getCorner().getCorner().x;
|
||||
final int blockZ = pos.getCorner().getCorner().z;
|
||||
final int perRenderWidth = 1 << render.getDataDetail();
|
||||
final int perDataWidth = 1 << data.dataDetail;
|
||||
if (data.dataDetail == render.getDataDetail()) {
|
||||
if (renderOffsetX < 0 || renderOffsetX+16 > render.getDataSize() || renderOffsetZ < 0 || renderOffsetZ+16 > render.getDataSize())
|
||||
throw new IllegalArgumentException("Data offset is out of bounds");
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
ColumnArrayView columnArrayView = render.getVerticalDataView(renderOffsetX + x, renderOffsetZ + z);
|
||||
SingleFullArrayView fullArrayView = data.get(x, z);
|
||||
convertColumnData(level, blockX + perRenderWidth * (renderOffsetX+x),
|
||||
blockZ + perRenderWidth * (renderOffsetZ+z),
|
||||
columnArrayView, fullArrayView);
|
||||
if (fullArrayView.doesItExist()) LodUtil.assertTrue(render.doesItExist(renderOffsetX + x, renderOffsetZ + z));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final int dataPerRender = 1 << (render.getDataDetail() - data.dataDetail);
|
||||
final int dataSize = 16 / dataPerRender;
|
||||
final int vertSize = render.getVerticalSize();
|
||||
long[] tempRender = new long[dataPerRender * dataPerRender * vertSize];
|
||||
if (renderOffsetX < 0 || renderOffsetX+dataSize > render.getDataSize() || renderOffsetZ < 0 || renderOffsetZ+dataSize > render.getDataSize())
|
||||
throw new IllegalArgumentException("Data offset is out of bounds");
|
||||
for (int x = 0; x < dataSize; x++) {
|
||||
for (int z = 0; z < dataSize; z++) {
|
||||
|
||||
ColumnQuadView tempQuadView = new ColumnQuadView(tempRender, dataPerRender, vertSize, 0, 0, dataPerRender, dataPerRender);
|
||||
for (int ox = 0; ox < dataPerRender; ox++) {
|
||||
for (int oz = 0; oz < dataPerRender; oz++) {
|
||||
ColumnArrayView columnArrayView = tempQuadView.get(ox, oz);
|
||||
SingleFullArrayView fullArrayView = data.get(x*dataPerRender+ox, z*dataPerRender+oz);
|
||||
convertColumnData(level, blockX + perRenderWidth * (renderOffsetX+x) + perDataWidth * ox,
|
||||
blockZ + perRenderWidth * (renderOffsetZ+z) + perDataWidth * oz,
|
||||
columnArrayView, fullArrayView);
|
||||
}
|
||||
}
|
||||
ColumnArrayView downSampledArrayView = render.getVerticalDataView(renderOffsetX + x, renderOffsetZ + z);
|
||||
downSampledArrayView.mergeMultiDataFrom(tempQuadView);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void convertColumnData(IClientLevel level, int blockX, int blockZ, ColumnArrayView columnArrayView, SingleFullArrayView fullArrayView) {
|
||||
if (!fullArrayView.doesItExist()) return;
|
||||
// TODO: Set gen mode
|
||||
|
||||
@@ -24,13 +24,13 @@ public class LodDataBuilder {
|
||||
IBiomeWrapper biome = chunk.getBiome(x, lastY, z);
|
||||
IBlockStateWrapper blockState = AIR;
|
||||
int mappedId = chunkData.getMapping().setAndGetId(biome, blockState);
|
||||
byte light = (byte) (chunk.getBlockLight(x,lastY,z) << 4 + chunk.getSkyLight(x,lastY,z));
|
||||
byte light = (byte) ((chunk.getBlockLight(x,lastY,z) << 4) + chunk.getSkyLight(x,lastY,z));
|
||||
int y=chunk.getMaxY(x, z);
|
||||
|
||||
for (; y>=chunk.getMinBuildHeight(); y--) {
|
||||
IBiomeWrapper newBiome = chunk.getBiome(x, y, z);
|
||||
IBlockStateWrapper newBlockState = chunk.getBlockState(x, y, z);
|
||||
byte newLight = (byte) (chunk.getBlockLight(x,y,z) << 4 + chunk.getSkyLight(x,y,z));
|
||||
byte newLight = (byte) ((chunk.getBlockLight(x,y,z) << 4) + chunk.getSkyLight(x,y,z));
|
||||
|
||||
if (!newBiome.equals(biome) || !newBlockState.equals(blockState)) {
|
||||
longs.add(FullFormat.encode(mappedId, lastY-y, y+1 - chunk.getMinBuildHeight(), light));
|
||||
|
||||
@@ -414,7 +414,7 @@ public class LodQuadTree implements AutoCloseable {
|
||||
}
|
||||
if (section.childCount == 4) section.disableRender();
|
||||
if (section.childCount == 0) section.enableRender(level, this);
|
||||
section.tick(this);
|
||||
section.tick(this, level);
|
||||
}
|
||||
|
||||
// Assertion steps
|
||||
|
||||
@@ -19,7 +19,6 @@ public class LodRenderSection {
|
||||
private LodRenderSource lodRenderSource;
|
||||
private CompletableFuture<LodRenderSource> loadFuture;
|
||||
private boolean isRenderEnabled = false;
|
||||
private IClientLevel level; //FIXME: Hack to pass level into enableRender() for renderSource
|
||||
|
||||
// Create sub region
|
||||
public LodRenderSection(DhSectionPos pos) {
|
||||
@@ -31,12 +30,10 @@ public class LodRenderSection {
|
||||
if (lodRenderSource != null) {
|
||||
lodRenderSource.enableRender(level, quadTree);
|
||||
}
|
||||
this.level = level;
|
||||
isRenderEnabled = true;
|
||||
}
|
||||
public void disableRender() {
|
||||
if (!isRenderEnabled) return;
|
||||
level = null;
|
||||
if (lodRenderSource != null) {
|
||||
lodRenderSource.disableRender();
|
||||
}
|
||||
@@ -55,13 +52,15 @@ public class LodRenderSection {
|
||||
loadFuture = renderDataProvider.read(pos);
|
||||
}
|
||||
|
||||
public void tick(LodQuadTree quadTree) {
|
||||
public void tick(LodQuadTree quadTree, IClientLevel level) {
|
||||
if (loadFuture != null && loadFuture.isDone()) {
|
||||
lodRenderSource = loadFuture.join();
|
||||
loadFuture = null;
|
||||
if (isRenderEnabled) {
|
||||
lodRenderSource.enableRender(level, quadTree);
|
||||
}
|
||||
} else if (lodRenderSource != null) {
|
||||
lodRenderSource.flushWrites(level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +105,6 @@ public class LodRenderSection {
|
||||
", lodRenderSource=" + lodRenderSource +
|
||||
", loadFuture=" + loadFuture +
|
||||
", isRenderEnabled=" + isRenderEnabled +
|
||||
", level=" + level +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,23 +4,18 @@ import com.seibel.lod.core.a7.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.a7.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.a7.datatype.RenderSourceLoader;
|
||||
import com.seibel.lod.core.a7.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.a7.datatype.full.FullFormat;
|
||||
import com.seibel.lod.core.a7.datatype.transform.DataRenderTransformer;
|
||||
import com.seibel.lod.core.a7.level.IClientLevel;
|
||||
import com.seibel.lod.core.a7.level.ILevel;
|
||||
import com.seibel.lod.core.a7.pos.DhLodPos;
|
||||
import com.seibel.lod.core.a7.save.io.MetaFile;
|
||||
import com.seibel.lod.core.a7.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.a7.save.io.file.DataMetaFile;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class RenderMetaFile extends MetaFile {
|
||||
@@ -42,7 +37,7 @@ public class RenderMetaFile extends MetaFile {
|
||||
|
||||
CompletableFuture<LodRenderSource> source = _readCached(data.get());
|
||||
if (source == null) return;
|
||||
if (source.isDone()) source.join().update(chunkData);
|
||||
if (source.isDone()) source.join().write(chunkData);
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> flushAndSave(ExecutorService renderCacheThread) {
|
||||
|
||||
@@ -20,7 +20,7 @@ public class DhClientServerWorld extends DhWorld implements IClientWorld, IServe
|
||||
private final HashMap<ILevelWrapper, DhClientServerLevel> levels;
|
||||
public final LocalSaveStructure saveStructure;
|
||||
public ExecutorService dhTickerThread = LodUtil.makeSingleThreadPool("DHTickerThread", 2);
|
||||
public EventLoop eventLoop = new EventLoop(dhTickerThread, this::_clientTick);
|
||||
public EventLoop eventLoop = new EventLoop(dhTickerThread, this::_clientTick); //TODO: Rate-limit the loop
|
||||
|
||||
public DhClientServerWorld() {
|
||||
super(WorldEnvironment.Client_Server);
|
||||
|
||||
Reference in New Issue
Block a user