Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package me.cortex.voxy.client.core.rendering.building;

import java.util.List;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.StampedLock;
import java.util.function.Consumer;

import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import me.cortex.voxy.client.core.model.IdNotYetComputedException;
import me.cortex.voxy.client.core.model.ModelBakerySubsystem;
import me.cortex.voxy.common.thread.Service;
import me.cortex.voxy.common.thread.ServiceManager;
import me.cortex.voxy.common.util.Pair;
import me.cortex.voxy.common.world.VoxySectionExclusion;
import me.cortex.voxy.common.world.WorldEngine;
import me.cortex.voxy.common.world.WorldSection;
import me.cortex.voxy.common.world.other.Mapper;

import java.util.List;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.StampedLock;
import java.util.function.Consumer;

//TODO: Add a render cache


Expand Down Expand Up @@ -118,6 +119,9 @@ private void computeAndRequestRequiredModels(IntOpenHashSet seenMissedIds, World
}

private WorldSection acquireSection(long pos) {
if (VoxySectionExclusion.isLod0Excluded(pos)) {
return null;
}
return this.world.acquireIfExists(pos);
}

Expand All @@ -134,6 +138,24 @@ private void processJob(RenderDataFactory factory, IntOpenHashSet seenMissedIds)
//long time = BuiltSection.getTime();
boolean shouldFreeSection = true;

if (VoxySectionExclusion.isLod0Excluded(task.position)) {
long stamp = this.taskMapLock.writeLock();
var rtask = this.taskMap.remove(task.position);
this.taskMapLock.unlockWrite(stamp);
if (rtask != task) {
throw new IllegalStateException();
}
if (task.section != null) {
this.holdingSectionCount.decrementAndGet();
task.section.release();
task.section = null;
}
if (this.resultConsumer != null) {
this.resultConsumer.accept(BuiltSection.empty(task.position));
}
return;
}

WorldSection section;
if (task.section == null) {
section = this.acquireSection(task.position);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package me.cortex.voxy.common.config.section;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.function.LongConsumer;

import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.config.ConfigBuildCtx;
import me.cortex.voxy.common.config.storage.StorageBackend;
import me.cortex.voxy.common.config.storage.StorageConfig;
import me.cortex.voxy.common.util.ThreadLocalMemoryBuffer;
import me.cortex.voxy.common.world.SaveLoadSystem3;
import me.cortex.voxy.common.world.VoxySectionExclusion;
import me.cortex.voxy.common.world.WorldSection;
import me.cortex.voxy.common.world.other.Mapper;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.function.LongConsumer;

public class SectionSerializationStorage extends SectionStorage {
public static final int BIGGEST_SERIALIZED_SECTION_SIZE = 32 * 32 * 32 * 8 * 2 + 8;

Expand All @@ -25,6 +26,10 @@ public SectionSerializationStorage(StorageBackend storageBackend) {
private static final ThreadLocalMemoryBuffer MEMORY_CACHE = new ThreadLocalMemoryBuffer(BIGGEST_SERIALIZED_SECTION_SIZE + 1024);

public int loadSection(WorldSection into) {
if (into.lvl == 0 && VoxySectionExclusion.isMinecraftSectionExcluded(into.x, into.y, into.z)) {
Arrays.fill(into._unsafeGetRawDataArray(), Mapper.AIR);
return 1;
}
var data = this.backend.getSectionData(into.key, MEMORY_CACHE.get().createUntrackedUnfreeableReference());
if (data != null) {
if (!SaveLoadSystem3.deserialize(into, data)) {
Expand All @@ -34,6 +39,7 @@ public int loadSection(WorldSection into) {
Logger.error("Section " + into.lvl + ", " + into.x + ", " + into.y + ", " + into.z + " was unable to load, removing");
return -1;
} else {
VoxySectionExclusion.carveExcludedVoxels(into);
return 0;
}
} else {
Expand Down
101 changes: 101 additions & 0 deletions src/main/java/me/cortex/voxy/common/world/VoxySectionExclusion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package me.cortex.voxy.common.world;

import java.util.Arrays;

import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.world.other.Mapper;

/**
* Hardcoded Voxy skip region. Vanilla/Sodium still render this volume while in render distance;
* Voxy must not ingest, load, or mesh it.
*
* Inclusive block AABB: (6000, 78, 224) to (6065, 179, 288).
* LOD-0 WorldSections are 32^3 ({@code block >> 5}), so the covering cells are:
* sx 187..189 (blocks 5984..6079),
* sy 2..5 (blocks 64..191),
* sz 7..9 (blocks 224..319).
*/
public final class VoxySectionExclusion {
private static final int MIN_X = 6000;
private static final int MIN_Y = 78;
private static final int MIN_Z = 224;
private static final int MAX_X = 6065;
private static final int MAX_Y = 179;
private static final int MAX_Z = 288;

private VoxySectionExclusion() {}

public static boolean isLod0Excluded(long pos) {
int chunky_x= WorldEngine.getX(pos);
int x = chunky_x * 32;
int chunky_y = WorldEngine.getY(pos);
int y = chunky_y * 32;
int chunky_z = WorldEngine.getZ(pos);
int z= chunky_z * 32;
// Logger.info("!!!!!!!! isLod0Excluded called: " + x + ", " + y + ", " + z);

return isMinecraftSectionExcluded(x, y, z);
}

/** Minecraft 16^3 section coords; skipped if they sit in an excluded LOD-0 cell. */
public static boolean isMinecraftSectionExcluded(int x, int y, int z) {
return x >= MIN_X && x <= MAX_X && y >= MIN_Y && y <= MAX_Y && z >= MIN_Z && z <= MAX_Z;
}

public static boolean intersectsWorldSection(int lvl, int x, int y, int z) {
int shift = 5 + lvl;
int size = 32 << lvl;
int minX = x << shift;
int minY = y << shift;
int minZ = z << shift;
return aabbIntersects(minX, minY, minZ, minX + size - 1, minY + size - 1, minZ + size - 1);
}

public static void carveExcludedVoxels(WorldSection section) {
if (section.lvl == 0) {
if (isMinecraftSectionExcluded(section.x, section.y, section.z)) {
Arrays.fill(section._unsafeGetRawDataArray(), Mapper.AIR);
}
return;
}
if (!intersectsWorldSection(section.lvl, section.x, section.y, section.z)) {
return;
}

int shift = 5 + section.lvl;
int sample = 1 << section.lvl;
int baseX = section.x << shift;
int baseY = section.y << shift;
int baseZ = section.z << shift;
long[] data = section._unsafeGetRawDataArray();

for (int lx = 0; lx < 32; lx++) {
int vx0 = baseX + (lx * sample);
int vx1 = vx0 + sample - 1;
if (vx1 < MIN_X || vx0 > MAX_X) {
continue;
}
for (int lz = 0; lz < 32; lz++) {
int vz0 = baseZ + (lz * sample);
int vz1 = vz0 + sample - 1;
if (vz1 < MIN_Z || vz0 > MAX_Z) {
continue;
}
for (int ly = 0; ly < 32; ly++) {
int vy0 = baseY + (ly * sample);
int vy1 = vy0 + sample - 1;
if (vy1 < MIN_Y || vy0 > MAX_Y) {
continue;
}
data[WorldSection.getIndex(lx, ly, lz)] = Mapper.AIR;
}
}
}
}

private static boolean aabbIntersects(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
return minX <= MAX_X && maxX >= MIN_X
&& minY <= MAX_Y && maxY >= MIN_Y
&& minZ <= MAX_Z && maxZ >= MIN_Z;
}
}
8 changes: 6 additions & 2 deletions src/main/java/me/cortex/voxy/common/world/WorldUpdater.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package me.cortex.voxy.common.world;

import me.cortex.voxy.common.voxelization.VoxelizedSection;
import static me.cortex.voxy.common.world.WorldEngine.MAX_LOD_LAYER;
import static me.cortex.voxy.common.world.WorldEngine.UPDATE_TYPE_BLOCK_BIT;
import static me.cortex.voxy.common.world.WorldEngine.UPDATE_TYPE_CHILD_EXISTENCE_BIT;
import me.cortex.voxy.common.world.other.Mapper;
import me.cortex.voxy.commonImpl.VoxyCommon;

import static me.cortex.voxy.common.world.WorldEngine.*;

public class WorldUpdater {
//Executes an update to the world and automatically updates all the parent mip layers up to level 4 (e.g. where 1 chunk section is 1 block big)

Expand All @@ -19,6 +20,9 @@ public static void insertUpdate(WorldEngine into, VoxelizedSection section) {//T
}

if (!into.isLive) throw new IllegalStateException("World is not live");
if (VoxySectionExclusion.isMinecraftSectionExcluded(section.x, section.y, section.z)) {
return;
}
boolean shouldCheckEmptiness = false;
WorldSection previousSection = null;
for (int lvl = 0; lvl <= MAX_LOD_LAYER; lvl++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package me.cortex.voxy.common.world.service;

import java.util.concurrent.ConcurrentLinkedDeque;

import org.jetbrains.annotations.NotNull;

import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.thread.Service;
import me.cortex.voxy.common.thread.ServiceManager;
Expand All @@ -17,9 +21,6 @@
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.lighting.LayerLightSectionStorage;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.ConcurrentLinkedDeque;

public class VoxelIngestService {
private static final ThreadLocal<VoxelizedSection> SECTION_CACHE = ThreadLocal.withInitial(VoxelizedSection::createEmpty);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
package me.cortex.voxy.commonImpl.importers;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Predicate;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.lwjgl.system.MemoryUtil;

import com.mojang.serialization.Codec;

import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.thread.Service;
import me.cortex.voxy.common.thread.ServiceManager;
Expand All @@ -22,28 +43,13 @@
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.*;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.PalettedContainerFactory;
import net.minecraft.world.level.chunk.PalettedContainerRO;
import net.minecraft.world.level.chunk.Strategy;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.chunk.storage.RegionFileVersion;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.lwjgl.system.MemoryUtil;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class WorldImporter implements IDataImporter {
private final WorldEngine world;
Expand Down