Continued work
This commit is contained in:
@@ -22,12 +22,12 @@ import net.minecraft.client.MinecraftClient;
|
|||||||
public class DistanceTracker {
|
public class DistanceTracker {
|
||||||
private final TransitionRing2D[] rings;
|
private final TransitionRing2D[] rings;
|
||||||
private final RenderTracker tracker;
|
private final RenderTracker tracker;
|
||||||
public DistanceTracker(RenderTracker tracker, int rings) {
|
private final int scale;
|
||||||
|
|
||||||
|
public DistanceTracker(RenderTracker tracker, int rings, int scale) {
|
||||||
this.rings = new TransitionRing2D[rings];
|
this.rings = new TransitionRing2D[rings];
|
||||||
this.tracker = tracker;
|
this.tracker = tracker;
|
||||||
|
this.scale = scale;
|
||||||
//NOTE: This is in our render distance units, to convert to chunks at lvl 0 multiply by 2
|
|
||||||
int DIST = 16;//24;
|
|
||||||
|
|
||||||
this.rings[0] = new TransitionRing2D(5, (int) Math.ceil(MinecraftClient.getInstance().gameRenderer.getViewDistance()/16)/2, (x, z)->{
|
this.rings[0] = new TransitionRing2D(5, (int) Math.ceil(MinecraftClient.getInstance().gameRenderer.getViewDistance()/16)/2, (x, z)->{
|
||||||
if (false) {
|
if (false) {
|
||||||
@@ -42,9 +42,12 @@ public class DistanceTracker {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//The rings 0+ start at 64 vanilla rd, no matter what the game is set at, that is if the game is set to 32 rd
|
||||||
|
// there will still be 32 chunks untill the first lod drop
|
||||||
|
// if the game is set to 16, then there will be 48 chunks until the drop
|
||||||
for (int i = 1; i < rings; i++) {
|
for (int i = 1; i < rings; i++) {
|
||||||
int capRing = i;
|
int capRing = i;
|
||||||
this.rings[i] = new TransitionRing2D(5+i, DIST, (x, z) -> this.dec(capRing, x, z), (x, z) -> this.inc(capRing, x, z));
|
this.rings[i] = new TransitionRing2D(5+i, scale, (x, z) -> this.dec(capRing, x, z), (x, z) -> this.inc(capRing, x, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +70,7 @@ public class DistanceTracker {
|
|||||||
//if the center suddenly changes (say more than 1<<(7+lodlvl) block) then invalidate the entire ring and recompute
|
//if the center suddenly changes (say more than 1<<(7+lodlvl) block) then invalidate the entire ring and recompute
|
||||||
// the lod sections
|
// the lod sections
|
||||||
public void setCenter(int x, int y, int z) {
|
public void setCenter(int x, int y, int z) {
|
||||||
for (var ring : rings) {
|
for (var ring : this.rings) {
|
||||||
if (ring != null) {
|
if (ring != null) {
|
||||||
ring.update(x, z);
|
ring.update(x, z);
|
||||||
}
|
}
|
||||||
@@ -75,6 +78,16 @@ public class DistanceTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void init(int x, int z) {
|
public void init(int x, int z) {
|
||||||
|
//Radius of chunks to enqueue
|
||||||
|
int SIZE = 40;
|
||||||
|
//Insert highest LOD level
|
||||||
|
for (int ox = -SIZE; ox <= SIZE; ox++) {
|
||||||
|
for (int oz = -SIZE; oz <= SIZE; oz++) {
|
||||||
|
this.inc(4, (x>>(5+this.rings.length-1)) + ox, (z>>(5+this.rings.length-1)) + oz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int i = this.rings.length-1; 0 <= i; i--) {
|
for (int i = this.rings.length-1; 0 <= i; i--) {
|
||||||
if (this.rings[i] != null) {
|
if (this.rings[i] != null) {
|
||||||
this.rings[i].fill(x, z);
|
this.rings[i].fill(x, z);
|
||||||
@@ -214,6 +227,10 @@ public class DistanceTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fill(int x, int z) {
|
public void fill(int x, int z) {
|
||||||
|
this.fill(x, z, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fill(int x, int z, Transition2DCallback outsideCallback) {
|
||||||
int cx = x>>this.shiftSize;
|
int cx = x>>this.shiftSize;
|
||||||
int cz = z>>this.shiftSize;
|
int cz = z>>this.shiftSize;
|
||||||
|
|
||||||
@@ -223,6 +240,15 @@ public class DistanceTracker {
|
|||||||
for (int c = -b; c <= b; c++) {
|
for (int c = -b; c <= b; c++) {
|
||||||
this.enter.callback(a + cx, c + cz);
|
this.enter.callback(a + cx, c + cz);
|
||||||
}
|
}
|
||||||
|
if (outsideCallback != null) {
|
||||||
|
for (int c = -this.radius; c < -b; c++) {
|
||||||
|
outsideCallback.callback(a + cx, c + cz);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int c = b+1; c <= this.radius; c++) {
|
||||||
|
outsideCallback.callback(a + cx, c + cz);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentX = cx;
|
this.currentX = cx;
|
||||||
|
|||||||
@@ -80,7 +80,8 @@ public class VoxelCore {
|
|||||||
this.world.setRenderTracker(this.renderTracker);
|
this.world.setRenderTracker(this.renderTracker);
|
||||||
this.renderTracker.setRenderGen(this.renderGen);
|
this.renderTracker.setRenderGen(this.renderGen);
|
||||||
|
|
||||||
this.distanceTracker = new DistanceTracker(this.renderTracker, 5);
|
//To get to chunk scale multiply the scale by 2, the scale is after how many chunks does the lods halve
|
||||||
|
this.distanceTracker = new DistanceTracker(this.renderTracker, 5, 16);
|
||||||
|
|
||||||
this.postProcessing = new PostProcessing();
|
this.postProcessing = new PostProcessing();
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ public abstract class AbstractFarWorldRenderer {
|
|||||||
//it shouldent matter if its called multiple times a frame however, as its synced with fences
|
//it shouldent matter if its called multiple times a frame however, as its synced with fences
|
||||||
UploadStream.INSTANCE.tick();
|
UploadStream.INSTANCE.tick();
|
||||||
|
|
||||||
|
|
||||||
//Update the lightmap
|
//Update the lightmap
|
||||||
{
|
{
|
||||||
long upload = UploadStream.INSTANCE.upload(this.lightDataBuffer, 0, 256*4);
|
long upload = UploadStream.INSTANCE.upload(this.lightDataBuffer, 0, 256*4);
|
||||||
@@ -88,7 +87,9 @@ public abstract class AbstractFarWorldRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Upload any new geometry
|
||||||
this.geometry.uploadResults();
|
this.geometry.uploadResults();
|
||||||
|
|
||||||
//Upload any block state changes
|
//Upload any block state changes
|
||||||
while (!this.stateUpdateQueue.isEmpty()) {
|
while (!this.stateUpdateQueue.isEmpty()) {
|
||||||
var stateUpdate = this.stateUpdateQueue.pop();
|
var stateUpdate = this.stateUpdateQueue.pop();
|
||||||
@@ -98,6 +99,7 @@ public abstract class AbstractFarWorldRenderer {
|
|||||||
MemoryUtil.memPutInt(ptr, faceColour); ptr+=4;
|
MemoryUtil.memPutInt(ptr, faceColour); ptr+=4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Upload any biome changes
|
//Upload any biome changes
|
||||||
while (!this.biomeUpdateQueue.isEmpty()) {
|
while (!this.biomeUpdateQueue.isEmpty()) {
|
||||||
var biomeUpdate = this.biomeUpdateQueue.pop();
|
var biomeUpdate = this.biomeUpdateQueue.pop();
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import me.cortex.voxelmon.core.gl.GlBuffer;
|
|||||||
import me.cortex.voxelmon.core.gl.GlFence;
|
import me.cortex.voxelmon.core.gl.GlFence;
|
||||||
import me.cortex.voxelmon.core.gl.GlPersistentMappedBuffer;
|
import me.cortex.voxelmon.core.gl.GlPersistentMappedBuffer;
|
||||||
import me.cortex.voxelmon.core.util.AllocationArena;
|
import me.cortex.voxelmon.core.util.AllocationArena;
|
||||||
|
import org.lwjgl.opengl.GL42;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
@@ -16,6 +17,7 @@ import static org.lwjgl.opengl.ARBMapBufferRange.*;
|
|||||||
import static org.lwjgl.opengl.GL11.glFinish;
|
import static org.lwjgl.opengl.GL11.glFinish;
|
||||||
import static org.lwjgl.opengl.GL42.glMemoryBarrier;
|
import static org.lwjgl.opengl.GL42.glMemoryBarrier;
|
||||||
import static org.lwjgl.opengl.GL42C.GL_BUFFER_UPDATE_BARRIER_BIT;
|
import static org.lwjgl.opengl.GL42C.GL_BUFFER_UPDATE_BARRIER_BIT;
|
||||||
|
import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BARRIER_BIT;
|
||||||
import static org.lwjgl.opengl.GL44.GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT;
|
import static org.lwjgl.opengl.GL44.GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT;
|
||||||
|
|
||||||
public class UploadStream {
|
public class UploadStream {
|
||||||
@@ -81,14 +83,15 @@ public class UploadStream {
|
|||||||
}
|
}
|
||||||
this.flushList.clear();
|
this.flushList.clear();
|
||||||
}
|
}
|
||||||
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
|
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT);
|
||||||
|
|
||||||
//Execute all the copies
|
//Execute all the copies
|
||||||
for (var entry : this.uploadList) {
|
for (var entry : this.uploadList) {
|
||||||
glCopyNamedBufferSubData(this.uploadBuffer.id, entry.target.id, entry.uploadOffset, entry.targetOffset, entry.size);
|
glCopyNamedBufferSubData(this.uploadBuffer.id, entry.target.id, entry.uploadOffset, entry.targetOffset, entry.size);
|
||||||
}
|
}
|
||||||
this.uploadList.clear();
|
this.uploadList.clear();
|
||||||
|
|
||||||
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
|
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT);
|
||||||
|
|
||||||
this.caddr = -1;
|
this.caddr = -1;
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import net.minecraft.nbt.NbtOps;
|
|||||||
import net.minecraft.nbt.NbtTagSizeTracker;
|
import net.minecraft.nbt.NbtTagSizeTracker;
|
||||||
import net.minecraft.registry.entry.RegistryEntry;
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
import net.minecraft.stat.Stat;
|
import net.minecraft.stat.Stat;
|
||||||
|
import net.minecraft.util.Pair;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
@@ -32,8 +33,8 @@ public class Mapper {
|
|||||||
private static final int BIOME_TYPE = 2;
|
private static final int BIOME_TYPE = 2;
|
||||||
|
|
||||||
private final StorageBackend storage;
|
private final StorageBackend storage;
|
||||||
public static final int UNKNOWN_MAPPING = -1;
|
public static final long UNKNOWN_MAPPING = -1;
|
||||||
public static final int AIR = 0;
|
public static final long AIR = 0;
|
||||||
|
|
||||||
private final Map<BlockState, StateEntry> block2stateEntry = new ConcurrentHashMap<>(2000,0.75f, 10);
|
private final Map<BlockState, StateEntry> block2stateEntry = new ConcurrentHashMap<>(2000,0.75f, 10);
|
||||||
private final ObjectArrayList<StateEntry> blockId2stateEntry = new ObjectArrayList<>();
|
private final ObjectArrayList<StateEntry> blockId2stateEntry = new ObjectArrayList<>();
|
||||||
@@ -62,6 +63,11 @@ public class Mapper {
|
|||||||
return ((id>>27)&((1<<20)-1)) == 0;
|
return ((id>>27)&((1<<20)-1)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean shouldRenderFace(int dirId, long self, long other) {
|
||||||
|
//TODO: fixme make it be with respect to the type itself e.g. water, glass etc
|
||||||
|
return isTranslucent(other);
|
||||||
|
}
|
||||||
|
|
||||||
public void setCallbacks(Consumer<StateEntry> stateCallback, Consumer<BiomeEntry> biomeCallback) {
|
public void setCallbacks(Consumer<StateEntry> stateCallback, Consumer<BiomeEntry> biomeCallback) {
|
||||||
this.newStateCallback = stateCallback;
|
this.newStateCallback = stateCallback;
|
||||||
this.newBiomeCallback = biomeCallback;
|
this.newBiomeCallback = biomeCallback;
|
||||||
@@ -71,15 +77,17 @@ public class Mapper {
|
|||||||
var mappings = this.storage.getIdMappings();
|
var mappings = this.storage.getIdMappings();
|
||||||
List<StateEntry> sentries = new ArrayList<>();
|
List<StateEntry> sentries = new ArrayList<>();
|
||||||
List<BiomeEntry> bentries = new ArrayList<>();
|
List<BiomeEntry> bentries = new ArrayList<>();
|
||||||
|
List<Pair<byte[], Integer>> sentryErrors = new ArrayList<>();
|
||||||
|
|
||||||
for (var entry : mappings.int2ObjectEntrySet()) {
|
for (var entry : mappings.int2ObjectEntrySet()) {
|
||||||
int entryType = entry.getIntKey()>>>30;
|
int entryType = entry.getIntKey()>>>30;
|
||||||
int id = entry.getIntKey() & ((1<<30)-1);
|
int id = entry.getIntKey() & ((1<<30)-1);
|
||||||
if (entryType == BLOCK_STATE_TYPE) {
|
if (entryType == BLOCK_STATE_TYPE) {
|
||||||
var sentry = StateEntry.deserialize(id, entry.getValue());
|
var sentry = StateEntry.deserialize(id, entry.getValue());
|
||||||
if (sentry.state.isAir()) {
|
if (sentry.state.isAir()) {
|
||||||
System.err.println("Deserialization had air, probably corrupt, Inserting garbage type");
|
System.err.println("Deserialization was air, removed block");
|
||||||
sentry = new StateEntry(id, Block.STATE_IDS.get(new Random().nextInt(Block.STATE_IDS.size()-1)));
|
sentryErrors.add(new Pair<>(entry.getValue(), id));
|
||||||
//TODO THIS
|
continue;
|
||||||
}
|
}
|
||||||
sentries.add(sentry);
|
sentries.add(sentry);
|
||||||
var oldEntry = this.block2stateEntry.put(sentry.state, sentry);
|
var oldEntry = this.block2stateEntry.put(sentry.state, sentry);
|
||||||
@@ -97,6 +105,20 @@ public class Mapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//Insert garbage types into the mapping for those blocks, TODO:FIXME: Need to upgrade the type or have a solution to error blocks
|
||||||
|
var rand = new Random();
|
||||||
|
for (var error : sentryErrors) {
|
||||||
|
while (true) {
|
||||||
|
var state = new StateEntry(error.getRight(), Block.STATE_IDS.get(rand.nextInt(Block.STATE_IDS.size() - 1)));
|
||||||
|
if (this.block2stateEntry.put(state.state, state) == null) {
|
||||||
|
sentries.add(state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Insert into the arrays
|
//Insert into the arrays
|
||||||
sentries.stream().sorted(Comparator.comparing(a->a.id)).forEach(entry -> {
|
sentries.stream().sorted(Comparator.comparing(a->a.id)).forEach(entry -> {
|
||||||
if (this.blockId2stateEntry.size() != entry.id) {
|
if (this.blockId2stateEntry.size() != entry.id) {
|
||||||
|
|||||||
Reference in New Issue
Block a user